home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / ada / ada_tutr.dat < prev    next >
Text File  |  1988-03-25  |  427KB  |  7,384 lines

  1. 10321046105710601087109211061116112611361145115811691178118912001209122312481269128913061327134513541359136813741382140214121422142614321439146014811502152215301539154815581566157515841594161116261645166616731684169216991707171717251745176517861804182018301841185118611880190319261929193519411964197919992012202220422068209320972102210721262145216521752184219522132231225622762283229523042314232423442358238124052411241724222440246124812490249525022508251425212527255125762590259826062615262726442663268727042713272027312750277327952820283528492862287728902903291929312954297829862995300430163038306030783091310331143126315431723187320532213237325632733292331533333349336433763389340634253446346034723478348334893494351735373558357435963608361736263638365836793692371237233737375137643777379138133835386338793888390739223933394439593969398139974020403840594075409741144132415141724191421242274244426042814303432643454362438143924407442644434460447444924511451845324543455245604582460446214629464046494659467846944714473047514763477747914811483248474868488248994914492949434963498249915002501050325049506450835104510951155121513651565172519052095218523052415264528453025316533353485363538154035428544854665479549155035525553955575567558155935604561556285650566756865697571157185725573157495769578458125821582958375845585358615881589559215943595759705983600560306049606560816088609561036111611861436153616261786193620862206240626662886302631363266339635263746392640764296453646964886506652265396561658466046627665166756692670767226739675867716785679468126829685468666885689168996906691269296949696969876999701270267045706370817100710771157123713171397163718972037226724472537265727572857305732373417363738273877394740174207443745474767500750675167523753075547581760076197641765910921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210921092109210922353$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  2.                                                                    
  3.                                                                    
  4.                         C O N G R A T U L A T I O N S !            
  5.                                                                    
  6.                                                                    
  7.  
  8.  
  9.        You've successfully completed ADA-TUTR, the Interactive Ada Tutor.
  10.  
  11.  
  12.                  Your comments and suggestions are encouraged.
  13.                               Please send them to:
  14.  
  15.            Software Innovations Technology, Attention: John J. Herro
  16.                 1083 Mandarin Drive NE, Palm Bay, FL 32905-4706
  17.  
  18.  
  19.                                 Have a good day!
  20.  
  21.  
  22.                      2027$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          Thank you for using ADA-TUTR.
  23.  
  24.                              You left off at number
  25.  
  26.                                                    
  27.  
  28.                  Please write down this number so you can later
  29.                  resume the session exactly where you left off.
  30.  
  31.  
  32.                   Please send your comments and suggestions to
  33.  
  34.            Software Innovations Technology, Attention: John J. Herro
  35.                 1083 Mandarin Drive NE, Palm Bay, FL 32905-4706
  36.  
  37.  
  38.                 I hope to see you again soon.  Have a good day!
  39.  
  40.  
  41.  
  42.                                                1265Y102N100B100 100#105M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  43.  
  44.  
  45.  
  46.  
  47.                        Do you want to exit ADA-TUTR now?
  48. 1HPlease press Y for yes or N for no.           3663Y105N118$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                                                            
  49.                                                                             
  50.                               W E L C O M E   T O                           
  51.                                                                             
  52.                                 A D A - T U T R                             
  53.                                                                             
  54.                T H E   I N T E R A C T I V E   A D A   T U T O R            
  55.                                                                             
  56.                                  by John Herro                              
  57.  
  58.     Software Innovations Technology                  Serial #  12330
  59.         1083 Mandarin Drive NE                        Version  1.00
  60.        Palm Bay, FL  32905-4706                        25-MAR-1988
  61.             (407) 951-0233                    Copyright 1988  John J. Herro
  62.  
  63.     Shareware: Try ADA-TUTR free.  To use it after the free trial, individ-
  64.     uals must register and organizations must buy a license.  Both are very
  65.     inexpensive, and give many benefits.  See page 1 of PRINT.ME for infor-
  66.     mation.  Whether or not you use ADA-TUTR and register or buy a license,
  67.     please copy the complete program and give unmodified copies to others!
  68.  
  69.                          Have you used ADA-TUTR before?
  70. 1H        Please press Y for yes or N for no.  You need not hit ENTER.             1468#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  71.  
  72.                                  Welcome back!
  73.  
  74.  
  75.                    Please type the number where you left off.
  76.  
  77.   (If you don't know the number, type 106 and I'll take you to the main menu.)
  78.  
  79.  
  80. Please press ENTER after the number.
  81.       2354A104B107C108D109E110F111G112H113I114J115K116L117$$$$$$$$$$$$                                   MAIN MENU
  82.  
  83.  
  84. A  Restart the Program.                  G  Records, Arrays, and Assignment 3
  85.  
  86. B  Introduction                          H  Recursion and Assignment 4
  87.  
  88. C  The Format of an Ada Program          I  Subprograms and Packages
  89.  
  90. D  Generic Instantiation and             J  Additional Types, Exceptions,
  91.       Assignment 1                             TEXT_IO, and Assignment 5
  92.  
  93. E  Simple Declarations and Simple        K  Generics, Tasking, and Assignment 6
  94.       Attributes
  95.                                          L  Advanced Topics
  96. F  Operators, Control Constructs, and
  97.       Assignment 2                       X  Exit the Program.
  98. 1HPlease press a letter.                      1958A118B119C121D122E123F129M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  INTRODUCTION
  99.                                       MENU
  100.  
  101.  
  102.                  A  Welcome
  103.  
  104.                  B  Printed Course Notes
  105.  
  106.                  C  Do I Need an Ada Compiler for this Course?
  107.  
  108.                  D  What is Ada?
  109.  
  110.                  E  A Very Brief History of Ada
  111.  
  112.                  F  What is a "Validated" Ada Compiler?
  113.  
  114.  
  115.                  M  Go Back to the Main Menu.
  116.  
  117.                  X  Exit the Program.
  118. 1HPlease press a letter.                  1973A135B137C147D149E150F158G159M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          THE FORMAT OF AN ADA PROGRAM
  119.                                       MENU
  120.  
  121.  
  122.       A  Our First Ada Program               F  Numbers
  123.  
  124.       B  Local Declarations                  G  Making the Dot Notation
  125.                                                    Automatic
  126.       C  Capitalization and Spacing
  127.  
  128.       D  Comments                            M  Go Back to the Main Menu.
  129.  
  130.       E  Identifiers                         X  Exit the Program.
  131. 1HPlease press a letter.   1912A167B173C175D178M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                     GENERIC INSTANTIATION AND ASSIGNMENT 1
  132.                                       MENU
  133.  
  134.  
  135.                   A  Displaying Integers
  136.  
  137.                   B  Generic Instantiation
  138.  
  139.                   C  Outside Assignment 1 -
  140.                         Preparing to Run Ada on Your Computer
  141.  
  142.                   D  The Ada Library
  143.  
  144.  
  145.                   M  Go Back to the Main Menu.
  146.  
  147.                   X  Exit the Program.
  148. 1HPlease press a letter.                                                                1850A184B190C199D201M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   SIMPLE DECLARATIONS AND SIMPLE ATTRIBUTES
  149.                                       MENU
  150.  
  151.  
  152.                           A  Variables and Constants
  153.  
  154.                           B  Enumeration Types
  155.  
  156.                           C  Subtypes
  157.  
  158.                           D  Simple Attributes
  159.  
  160.  
  161.                           M  Go Back to the Main Menu.
  162.  
  163.                           X  Exit the Program.
  164. 1HPlease press a letter.                          2243A216B218C223D231E240F242G248H250I255J261K264M106$$$$$$$$$$$$                OPERATORS, CONTROL CONSTRUCTS, AND ASSIGNMENT 2
  165.                                       MENU
  166.  
  167.  
  168.      A  Operators                       H  Labels and GOTOs
  169.  
  170.      B  Range Tests                     I  The CASE Construct
  171.  
  172.      C  The Short Circuit Forms         J  Brief Overview of Functions
  173.  
  174.      D  The IF Block                    K  Outside Assignment 2 -
  175.                                               Exercise in Enumeration Types
  176.      E  WHILE Loops
  177.  
  178.      F  FOR Loops                       M  Go Back to the Main Menu
  179.  
  180.      G  The EXIT Statement              X  Exit the Program.
  181. 1HPlease press a letter.                                 2066A271B279C288D298E310F312M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       RECORDS, ARRAYS, AND ASSIGNMENT 3
  182.                                       MENU
  183.  
  184.  
  185.                           A  Records
  186.  
  187.                           B  Arrays
  188.  
  189.                           C  Multidimensional Arrays
  190.  
  191.                           D  Strings
  192.  
  193.                           E  Array Operators
  194.  
  195.                           F  Outside Assignment 3 -
  196.                                 Exercise in Records
  197.  
  198.  
  199.                           M  Go Back to the Main Menu.
  200.  
  201.                           X  Exit the Program.
  202. 1HPlease press a letter.          1844A318B325C330M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                           RECURSION AND ASSIGNMENT 4
  203.                                       MENU
  204.  
  205.  
  206.                          A  Recursion
  207.  
  208.                          B  The Tower of Hanoi Problem
  209.  
  210.                          C  Outside Assignment 4 -
  211.                                Exercise in Recursion
  212.  
  213.  
  214.                          M  Go Back to the Main Menu.
  215.  
  216.                          X  Exit the Program.
  217. 1HPlease press a letter.                                2036A334B344C351D359E367F382M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            SUBPROGRAMS AND PACKAGES
  218.                                       MENU
  219.  
  220.  
  221.                      A  Procedures and Functions
  222.  
  223.                      B  Default Parameters
  224.  
  225.                      C  Packages
  226.  
  227.                      D  Functions with Infix Notation
  228.  
  229.                      E  Information Hiding: Private Types
  230.  
  231.                      F  Type TEXT and Limited Private Types
  232.  
  233.  
  234.                      M  Go Back to the Main Menu.
  235.  
  236.                      X  Exit the Program.
  237. 1HPlease press a letter.                                        2070A396B413C415D421E438F448M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$            ADDITIONAL TYPES, EXCEPTIONS, TEXT_IO, AND ASSIGNMENT 5
  238.                                       MENU
  239.  
  240.  
  241.                      A  Access Types
  242.  
  243.                      B  User Defined Types and Portability
  244.  
  245.                      C  Derived Types
  246.  
  247.                      D  Exceptions
  248.  
  249.                      E  More About TEXT_IO
  250.  
  251.                      F  Outside Assignment 5 -
  252.                            Writing a Simple Line Editor
  253.  
  254.  
  255.                      M  Go Back to the Main Menu.
  256.  
  257.                      X  Exit the Program.
  258. 1HPlease press a letter.      1832A455B463C483M106$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      GENERICS, TASKING, AND ASSIGNMENT 6
  259.                                       MENU
  260.  
  261.  
  262.                           A  Generics
  263.  
  264.                           B  Tasking
  265.  
  266.                           C  Outside Assignment 6 -
  267.                                 Exercise in Tasking
  268.  
  269.  
  270.                           M  Go Back to the Main Menu.
  271.  
  272.                           X  Exit the Program.
  273. 1HPlease press a letter.                                            2371A487B489C491D496E503F512G515H521I522J529K532L538M106$$$$$$$$                                ADVANCED TOPICS
  274.                                       MENU
  275.  
  276.  
  277. A  Renaming                              H  Subprogram Parameters with Generics
  278.  
  279. B  Packages STANDARD and ASCII           I  Representation Clauses and SYSTEM
  280.  
  281. C  An Alternative to Infix Notation      J  Unchecked Conversion and Unchecked
  282.                                                Deallocation
  283. D  Record Discriminants and Record
  284.       Variants                           K  Pragmas
  285.  
  286. E  Fixed Point and Universal Types       L  Loose Ends and Pitfalls
  287.  
  288. F  More Attributes                       M  Go Back to the Main Menu.
  289.  
  290. G  SEQUENTIAL_IO and DIRECT_IO           X  Exit the Program.
  291. 1HPlease press a letter.     3456 119B104$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                                                       
  292.                                                                        
  293.                 WELCOME TO ADA-TUTR, THE INTERACTIVE ADA TUTOR!        
  294.                                                                        
  295.                                                                        
  296.  
  297. ADA-TUTR will make you an excellent Ada programmer in minimum time.  You should
  298. be familiar with at least one other high-level language (Basic, Pascal, etc.)
  299.  
  300. You can study as long as you like.  Whenever you're ready to exit the program,
  301. just type X.  Remember, typing X stops ADA-TUTR at any time.  I always ask you
  302. if you really want to exit the program.  This gives you a chance to go back to
  303. where you were, in case you typed X by mistake.  When you're ready to learn
  304. again, you'll be able to continue exactly where you left off.
  305.  
  306. ADA-TUTR works with monochrome as well as color monitors.  Please adjust the
  307. brightness and contrast of your monitor now.  The highlighted words should be
  308. noticeably brighter than the others, but everything should be easy to read.
  309.  
  310. Your questions, comments, and suggestions are encouraged.  Please send them to
  311.            Software Innovations Technology, Attention: John J. Herro
  312.                 1083 Mandarin Drive NE, Palm Bay, FL 32905-4706
  313. 1HPlease type a space to go on.  (You need not hit ENTER.)                    3031 120B118$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              PRINTED COURSE NOTES
  314.  
  315. To get the most from ADA-TUTR, you should have a printed copy of the PRINT.ME
  316. file.  If you haven't started printing the course notes yet, read this screen
  317. and then type X to exit the program temporarily.  Remember, you can leave
  318. ADA-TUTR at any time, and later pick up exactly where you left off.
  319.  
  320. Then, when the system prompt (usually C>) appears, type:
  321.  
  322.                                  PRINT PRINT.ME
  323.  
  324. You can then restart ADA-TUTR while your course notes are being printed.
  325. Please read through page 3 now.  If you got this far, you don't need page 4.
  326. Please read page 5 if you want to install ADA-TUTR on a non-PC computer, such
  327. as a mainframe.
  328.  
  329. If you're using a PC and you ever want to print the screen that's currently
  330. being displayed, simply hold a Shift key while pressing the PrtSc key.
  331.  
  332. Whenever you exit ADA-TUTR, I give you a number telling where you left off.
  333. (If you leave from here, the number will be 119.)  When you run ADA-TUTR again,
  334. I'll ask you to type that number.  If you type 119, you'll be right back here.
  335. 1HPlease type X to exit, a space to go on, or B to go back.                                             2933 121B119$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In addition to the printed course notes, we recommend (but don't require) that
  336. you have access to the Military Standard Ada Programming Language manual,
  337. ANSI/MIL-STD-1815A, 1983.  This volume is often called the Language Reference
  338. Manual, or LRM.  You'll probably find it in a public library, or perhaps in
  339. your company library.  If you can borrow an LRM, it's legal to copy the entire
  340. book.  You can also buy an LRM very inexpensively.
  341.  
  342. Although the LRM is a good reference, it's difficult reading and not a good
  343. learning tool.  With ADA-TUTR you probably won't need a textbook, but if you
  344. feel you do, try one of the following:
  345.  
  346.       1.  S. J. Young, AN INTRODUCTION TO ADA, Wiley and Sons, 1984
  347.  
  348.       2.  J. G. P. Barnes, PROGRAMMING IN ADA, Addison-Wesley, 1983
  349.  
  350.       3.  G. Booch, SOFTWARE ENGINEERING WITH ADA, Benjamin-Cummings, 1983
  351.  
  352. We have no financial interest in any of these authors or publishers; we simply
  353. selected three books out of many.  We don't recommend using books dated before
  354. 1983, because the Ada language changed then, and you'll be confused.
  355. 1HPlease type a space to go on, or B to go back.                                           2648 122B120$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   DO I NEED AN ADA COMPILER FOR THIS COURSE?
  356.  
  357. An Ada compiler is helpful, but not required.  As we go along, there will be
  358. six Outside Assignments; most of them ask you to write and compile a short Ada
  359. program.  If you don't have access to an Ada compiler, just skip the Outside
  360. Assignments.
  361.  
  362. A brief list of Ada compilers available for the PC and compatibles is in your
  363. printed course notes, on pages 2-3.  We tried to include all the popular Ada
  364. compilers, as we have no financial interest in any company mentioned in that
  365. list.  However, we might have missed some.  If you know of an Ada compiler that
  366. you think should be on that list, please contact us.
  367.  
  368. A screen editor / word processor is very helpful, and we can send you a copy of
  369. one free or nearly free.  Please see page 3 of your printed course notes for
  370. details.
  371.  
  372. That's enough discussion of what's recommended for ADA-TUTR.  Let's begin!
  373. 1HPlease type a space to go on, or B to go back.                            3020 123B121$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  WHAT IS ADA?
  374.  
  375. Ada is a modern language designed for programming large scale and real time
  376. systems.  Ada is also an excellent general purpose language.  It has many new
  377. features which help prevent errors and detect errors earlier.
  378.  
  379. However, Ada is much more than a new language.  It's also a new programming
  380. philosophy.  Beware of learning just "Ada syntax"; you'll wind up writing
  381. Basic-like (or Pascal-like, etc.) programs that happen to be coded in Ada.  If
  382. you do that, you'll lose the many benefits of Ada.  Unfortunately, you won't
  383. see why Ada is a new programming philosophy until later in this course.  (By
  384. the time we get to packages and information hiding, you'll be an enthusiastic
  385. convert.)  In the meantime, please take our word for it:  Ada is a whole new
  386. programming philosophy, not just another language.
  387.  
  388. Because of its many features, Ada is relatively complicated.  There's about
  389. seven times as much to learn as Pascal.  However, the effort pays great
  390. dividends.  Once you learn the language, Ada programs are easier to write,
  391. easier to read, and much easier to modify a month or a year later.
  392. 1HPlease type a space to go on, or B to go back.                                                        2726 124B122$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          A VERY BRIEF HISTORY OF ADA
  393.  
  394. Ada was named for Augusta Ada Byron, countess of Lovelace and daughter of the
  395. poet Lord Byron.  She worked with Charles Babbage on his Analytical Engine, and
  396. has been called the world's first programmer.  The Language Reference Manual
  397. (LRM) was given the number ANSI/MIL-STD-1815A because Augusta Ada Byron was
  398. born in 1815.
  399.  
  400. Ada was invented because the U.S. Department of Defense (DoD) realized that
  401. none of the existing languages was very suitable for real-time control of
  402. large, embedded systems.  An embedded system is a computer system inside a
  403. product other than a computer, such as an intelligent oven or a guided missile.
  404.  
  405. In 1977 the DoD issued a Request for Proposal to develop a new language; the
  406. leading four contenders were designated Blue, Red, Yellow, and Green.
  407. Eventually Green was selected to be Ada; it was designed by the company
  408. Honeywell Bull under the direction of Jean Ichbiah of France.
  409. 1HPlease type a space to go on, or B to go back.                                                  18172125112631274128B123$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In the author's opinion, which one of the following statements is true?
  410.  
  411.  
  412. 1.  Ada is simpler than Pascal.
  413.  
  414. 2.  Although Ada was designed for embedded systems, it makes a good general
  415.     purpose language.
  416.  
  417. 3.  Basic and Pascal programs can easily be translated into good Ada programs.
  418.  
  419. 4.  In languages that are simpler than Ada, errors are usually detected earlier
  420.     than in Ada.
  421. 1HPlease press 1, 2, 3, or 4, or B to go back.                                                           1431 129B124Q124$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!  Ada makes use of the latest advances in software engineering, so
  422. it makes an excellent general purpose language.
  423. 1HPlease type a space to go on, or B or Q to go back to the question.                                             1850 129B124Q124$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, Ada is more complicated than Pascal.  So far as the philosophy is
  424. concerned, Ada is an extension (or "superset") of Pascal.  However, in syntax
  425. Ada isn't a superset of Pascal; the Ada syntax is different.
  426.  
  427. Although Ada is more complicated than Pascal (and many other languages), it has
  428. many advantages.  These advantages pay dividends in reduced effort to develop
  429. and maintain programs.
  430. 1HPlease type a space to go on, or B or Q to go back to the question.                          1515 129B124Q124$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, it might be easy to translate Basic and Pascal programs into Ada, but the
  431. resulting programs wouldn't be very good, because they'd fail to take advantage
  432. of the features of Ada.
  433. 1HPlease type a space to go on, or B or Q to go back to the question.                                                             1756 129B124Q124$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, Ada has a reputation for detecting errors earlier than the simpler
  434. languages.  Ada detects errors at compile time that other languages detect at
  435. run time or not at all.  Examples are calling a subprogram with the wrong
  436. number of arguments, and unintentionally mixing different types in an
  437. expression.  We'll learn more about these things later.
  438. 1HPlease type a space to go on, or B or Q to go back to the question.                    2917T130F131B124$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      WHAT IS A "VALIDATED" ADA COMPILER?
  439.  
  440. Although the name "Ada" is no longer a trademark of the Department of Defense,
  441. the Ada Joint Program Office (AJPO) still validates Ada compilers.  Only
  442. validated compilers may display an emblem that says, "Validated Ada ... This
  443. product conforms to ANSI/MIL-STD-1815A as determined by the AJPO under its
  444. current testing procedures."
  445.  
  446. If a compiler conforms exactly to the standard, and isn't a subset or superset
  447. of Ada, it can be validated after passing an extensive suite of tests (called
  448. the Ada Compiler Validation Capability, or ACVC).  The Validation Certificate
  449. is good for only one year, after which the compiler must be retested.  This is
  450. done because the ACVC keeps growing.
  451.  
  452. An unnumbered page in the beginning of the LRM says that "Only compilers which
  453. have been validated ... shall be used in DoD systems."  Also, a 1987 DoD
  454. Directive (3405.2) says that only validated Ada compilers may be used on
  455. mission critical systems.
  456.  
  457.  
  458. True or False?  Subsets and supersets of standard Ada may be called "Ada."
  459. 1HPlease press T for true or F for false, or B to go back.                                                           1919 132B129Q129$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!  Compilers not conforming exactly to the Ada standard may be
  460. called "Ada."  This was true even when "Ada" was a DoD trademark.  A preface to
  461. the LRM says that compilers not conforming to the standard may be called "Ada"
  462. if there's a clear statement that they don't conform.
  463.  
  464. Of course, only validated Ada compilers are to be used on DoD systems, and
  465. validated compilers can't be subsets or supersets of standard Ada.
  466. 1HPlease type a space to go on, or B or Q to go back to the question.                                                         1922 132B129Q129$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$True.  It's a common misconception that subsets and supersets may not be called
  467. "Ada."  However, this was allowed even when "Ada" was a DoD trademark.  A
  468. preface to the LRM says that compilers not conforming to the standard may be
  469. called "Ada" if there's a clear statement that they don't conform.
  470.  
  471. It's true that only validated Ada compilers are to be used in DoD systems.
  472. Validated compilers can't be subsets or supersets of standard Ada.
  473. 1HPlease type a space to go on, or B or Q to go back to the question.                                                      1361F133T134B129$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$True or False?  The Validation tests are performed to provide reasonable
  474. assurance that a compiler is bug-free.
  475. 1HPlease press T for true or F for false, or B to go back.               1572 135B132Q132$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!  The Validation tests are performed to make sure that a compiler
  476. conforms to the Ada standard, and isn't a subset or superset.  A compiler isn't
  477. believed to be bug-free just because it earned a Validation Certificate.
  478. 1HPlease type a space to go on, or B or Q to go back to the question.    1616 135B132Q132$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$False.  That's a common misconception, but validation only determines that a
  479. compiler conforms exactly to the Ada standard, and isn't a subset or superset.
  480. A compiler isn't believed to be bug-free just because it earned a Validation
  481. Certificate.
  482. 1HPlease type a space to go on, or B or Q to go back to the question.                                                            3021 136B132$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             OUR FIRST ADA PROGRAM
  483.  
  484. Now let's look at a simple Ada program.  This program merely prints "Hello!" on
  485. the terminal.
  486.  
  487.                          with TEXT_IO;
  488.                          procedure HELLO is
  489.                          begin
  490.                             TEXT_IO.PUT_LINE("Hello!");
  491.                          end HELLO;
  492.  
  493. TEXT_IO is a "package" that comes with the Ada language.  We'll learn more
  494. about packages later.  TEXT_IO contains, among other things, a procedure
  495. PUT_LINE that takes one argument of type STRING and prints it on the terminal.
  496. In this case, the STRING argument is "Hello!".  Ada doesn't have any special
  497. I/O statements.  I/O is done by calling procedures that Ada provides for us.
  498.  
  499. Even though the package TEXT_IO comes with Ada, our procedure HELLO can't "see"
  500. it unless it says with TEXT_IO;.  With that statement, our procedure can call
  501. any procedure or function inside TEXT_IO.  We call a procedure by giving the
  502. package name (TEXT_IO), followed by a dot and the name of the procedure within
  503. the package.  Like Pascal and unlike Fortran, the word CALL isn't used in Ada.
  504. 1HPlease type a space to go on, or B to go back.                                                       3037 137B135$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         with TEXT_IO;
  505.                          procedure HELLO is
  506.                          begin
  507.                             TEXT_IO.PUT_LINE("Hello!");
  508.                          end HELLO;
  509.  
  510. The statement with TEXT_IO; is called a context clause because it specifies the
  511. "context" in which procedure HELLO is compiled.
  512.  
  513. In Ada a procedure can be called either from another procedure or as the main
  514. program.  In this example, HELLO is the main program; it calls PUT_LINE.
  515.  
  516. Every Ada statement, including the last, ends with a semicolon.  (Technically,
  517. the lines above without semicolons aren't statements.)  In Pascal, semicolons
  518. come between statements, but in Ada, a semicolon ends a statement.
  519.  
  520. In Ada, the end statement may optionally give the name of the procedure or
  521. function.  If a name is given, the compiler will check that it agrees with the
  522. name at the beginning.  If it doesn't agree, the compiler will issue a message.
  523.  
  524. The statements between begin and end (this program has only one) are called
  525. executable statements; when they're obeyed they're said to be executed.
  526. 1HPlease type a space to go on, or B to go back.                                       3059 138B136$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               LOCAL DECLARATIONS
  527.  
  528.                          with TEXT_IO;
  529.                          procedure HELLO is
  530.                             I    : INTEGER;
  531.                             X, Y : FLOAT;
  532.                          begin
  533.                             TEXT_IO.PUT_LINE("Hello!");
  534.                          end HELLO;
  535.  
  536. Local declarations may appear between procedure and begin.  This simple program
  537. doesn't need any, but we've added two declarative statements by way of example.
  538. Executable statements are said to be executed when they're obeyed, but when a
  539. declarative statement is obeyed, it's said to be elaborated.  Declarative
  540. statements are elaborated at run time, not compile time.
  541.  
  542. In this example, when the procedure is called (either from another procedure or
  543. as the main program), the declarations are elaborated and variables I, X, and Y
  544. are brought into existence.  Then the executable statement(s) are obeyed.  When
  545. the end statement is reached and the procedure returns, I, X, and Y go out of
  546. existence.  These three variables are local to procedure HELLO and can't be
  547. accessed from outside this procedure.
  548. 1HPlease type a space to go on, or B to go back.                 2946 139B137$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         with TEXT_IO;
  549.                          procedure HELLO is
  550.                             I    : INTEGER;
  551.                             X, Y : FLOAT;
  552.                          begin
  553.                             TEXT_IO.PUT_LINE("Hello!");
  554.                          end HELLO;
  555.  
  556. If HELLO is called again, I, X, and Y will again be brought into existence, but
  557. their previous values won't necessarily be remembered between calls.  (Of
  558. course, in this simple example, I, X, and Y aren't given values anyway.)
  559.  
  560. Like Pascal and unlike Basic and Fortran, every Ada variable must be declared.
  561. But unlike Pascal, Ada programs don't need to say "var".  Ada knows that the
  562. objects declared above are variables.  Constant declarations contain the
  563. reserved word constant and may or may not specify a type, as shown below.
  564.  
  565. Declarations are elaborated in order, top to bottom.  These two declarations
  566. must appear in the order shown, because the second refers to the first:
  567.  
  568.                       PI     : constant := 3.141592654;
  569.                       TWO_PI : constant FLOAT := 2.0 * PI;
  570. 1HPlease type a space to go on, or B to go back.                              1750314011412142B138$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  571.                          procedure HELLO is
  572.                2            I    : INTEGER;
  573.                             X, Y : FLOAT;
  574.                          begin
  575.                3            TEXT_IO.PUT_LINE("Hello!");
  576.                          end HELLO;
  577.  
  578. OK, in the program above, where are the executable statement(s)?
  579. 1HPlease press 1, 2, or 3, or B to go back.                          1839 143B139Q139$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  580.                          procedure HELLO is
  581.                2            I    : INTEGER;
  582.                             X, Y : FLOAT;
  583.                          begin
  584.                3            TEXT_IO.PUT_LINE("Hello!");
  585.                          end HELLO;
  586.  
  587. You're right!  Executable statements are placed between begin and end.
  588. 1HPlease type a space to go on, or B or Q to go back to the question.                                     1865 143B139Q139$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  589.                          procedure HELLO is
  590.                2            I    : INTEGER;
  591.                             X, Y : FLOAT;
  592.                          begin
  593.                3            TEXT_IO.PUT_LINE("Hello!");
  594.                          end HELLO;
  595.  
  596. No, with TEXT_IO; is a context clause.  Executable statements are placed
  597. between begin and end.
  598. 1HPlease type a space to go on, or B or Q to go back to the question.           1943 143B139Q139$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  599.                          procedure HELLO is
  600.                2            I    : INTEGER;
  601.                             X, Y : FLOAT;
  602.                          begin
  603.                3            TEXT_IO.PUT_LINE("Hello!");
  604.                          end HELLO;
  605.  
  606. No, declarative statements are placed between procedure and begin.  Executable
  607. statements are placed between begin and end.
  608. 1HPlease type a space to go on, or B or Q to go back to the question.                                 1726214411453146B139$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  609.                          procedure HELLO is
  610.                2            I    : INTEGER;
  611.                             X, Y : FLOAT;
  612.                          begin
  613.                3            TEXT_IO.PUT_LINE("Hello!");
  614.                          end HELLO;
  615.  
  616. Now, where are the local declaration(s)?
  617. 1HPlease press 1, 2, or 3, or B to go back.                                                  1842 147B143Q143$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  618.                          procedure HELLO is
  619.                2            I    : INTEGER;
  620.                             X, Y : FLOAT;
  621.                          begin
  622.                3            TEXT_IO.PUT_LINE("Hello!");
  623.                          end HELLO;
  624.  
  625. You're right!  Local declarations are placed between procedure and begin.
  626. 1HPlease type a space to go on, or B or Q to go back to the question.                                  1868 147B143Q143$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  627.                          procedure HELLO is
  628.                2            I    : INTEGER;
  629.                             X, Y : FLOAT;
  630.                          begin
  631.                3            TEXT_IO.PUT_LINE("Hello!");
  632.                          end HELLO;
  633.  
  634. No, with TEXT_IO; is a context clause.  Local declarations are placed between
  635. procedure and begin.
  636. 1HPlease type a space to go on, or B or Q to go back to the question.        1939 147B143Q143$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$               1         with TEXT_IO;
  637.                          procedure HELLO is
  638.                2            I    : INTEGER;
  639.                             X, Y : FLOAT;
  640.                          begin
  641.                3            TEXT_IO.PUT_LINE("Hello!");
  642.                          end HELLO;
  643.  
  644. No, executable statements are placed between begin and end.  Local declarations
  645. are placed between procedure and begin.
  646. 1HPlease type a space to go on, or B or Q to go back to the question.                                     2627 148B143$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                           CAPITALIZATION AND SPACING
  647.  
  648.                          with TEXT_IO;
  649.                          procedure HELLO is
  650.                             I    : INTEGER;
  651.                             X, Y : FLOAT;
  652.                          begin
  653.                             TEXT_IO.PUT_LINE("Hello!");
  654.                          end HELLO;
  655.  
  656. Except in quoted STRINGs like "Hello!", capitalization isn't important in Ada.
  657. The LRM shows all reserved words in lower case and all identifiers in upper
  658. case, so that's the style we're using in our examples.
  659.  
  660. In Ada, unlike Fortran, statements may begin anywhere on the line; columns
  661. aren't significant.  Most people indent the local declarations and the
  662. executable statements three spaces, as shown above.  Spaces and tabs may not
  663. appear within reserved words and identifiers, but they may freely be used
  664. between elements of the program.
  665. 1HPlease type a space to go on, or B to go back.                                                 2456 149B147$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         with TEXT_IO;
  666.                          procedure HELLO is
  667.                             I    : INTEGER;
  668.                             X, Y : FLOAT;
  669.                          begin
  670.                             TEXT_IO.PUT_LINE("Hello!");
  671.                          end HELLO;
  672.  
  673. Since a semicolon marks the end of a statement, we can put several statements
  674. on one line, like this:
  675.  
  676.                           I : INTEGER;   X, Y : FLOAT;
  677.  
  678. We can also continue a statement over several lines, breaking anywhere a space
  679. would be permitted, like this:
  680.  
  681.                                 TEXT_IO.
  682.                                      PUT_LINE(
  683.                                      "Hello!");
  684.  
  685. Most people follow the capitalization and spacing style of the LRM, so we'll do
  686. that in this course.
  687. 1HPlease type a space to go on, or B to go back.                    2847 150B148$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    COMMENTS
  688.  
  689.           with TEXT_IO;
  690.           procedure HELLO is
  691.              -- This program prints "Hello!" on the screen.
  692.              I    : INTEGER; -- These declarations aren't needed; they
  693.              X, Y : FLOAT;   -- were added only to provide examples.
  694.           begin
  695.              TEXT_IO.PUT_LINE("Hello!");
  696.           end HELLO;
  697.  
  698. Comments in Ada begin with a double hyphen (double minus sign) and continue
  699. through the end of the line.  No space is permitted inside the double hyphen.
  700. As shown, a comment can be an entire line, or it can follow code on a line.
  701.  
  702. Ada programs generally have less need for comments than programs written in
  703. other languages.  The reason is that, as we'll see, the identifiers can be as
  704. long as we like and can have very meaningful names.  Also, when we learn about
  705. named notation, we'll see that calls to subprograms can be made much more
  706. readable in Ada than in other languages.  These features and others tend to
  707. make Ada programs self documenting.
  708. 1HPlease type a space to go on, or B to go back.                             3055 151B149$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  IDENTIFIERS
  709.  
  710.                          with TEXT_IO;
  711.                          procedure HELLO is
  712.                             I    : INTEGER;
  713.                             X, Y : FLOAT;
  714.                          begin
  715.                             TEXT_IO.PUT_LINE("Hello!");
  716.                          end HELLO;
  717.  
  718. In this program, everything in capital letters is an identifier.  Ada
  719. identifiers may contain letters, digits, and underlines, but must start with a
  720. letter.  They may not contain spaces or other characters.  Identifiers may be
  721. as long as you like, up to the length of a line.  (The maximum line length
  722. depends on the particular implementation of Ada.)  All characters are
  723. significant, so THIS_IS_A_LONG_IDENTIFIER_1 and THIS_IS_A_LONG_IDENTIFIER_2 are
  724. distinct.  Since underlines are significant, A_B is different from AB.  Every
  725. underline must be followed by a letter or a digit.  Thus, you can't have two
  726. underlines together, and an identifier can't end in an underline.
  727.  
  728. Reserved words may not be used as identifiers.  The 63 Ada reserved words are
  729. listed on page 6 of your printed course notes, and in section 2.9 of the LRM.
  730. 1HPlease type a space to go on, or B to go back.                     1658315211532154415551566157B150$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  731.  
  732.                  2.  BEGIN
  733.  
  734.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  735.  
  736.                  4.  SYS$QIO
  737.  
  738.                  5.  NUMBER_OF_TARGETS_
  739.  
  740.                  6.  MAX SPEED
  741.  
  742.  
  743. Only one of the above is a legal Ada identifier.  Which is it?
  744. 1HPlease press 1, 2, 3, 4, 5, or 6, or B to go back.                  2022 158B151Q151$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  745.  
  746.                  2.  BEGIN
  747.  
  748.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  749.  
  750.                  4.  SYS$QIO
  751.  
  752.                  5.  NUMBER_OF_TARGETS_
  753.  
  754.                  6.  MAX SPEED
  755.  
  756.  
  757. You're right!  An Ada identifier can be as long as we like (up to the length of
  758. a line), and upper/lower case isn't important in Ada.
  759.  
  760. Number 1 begins with a digit, 2 is a reserved word, 4 has a dollar sign, 5 has
  761. a trailing underline, and 6 has a space.
  762. 1HPlease type a space to go on, or B or Q to go back to the question.                                                      1715 158B151Q151$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  763.  
  764.                  2.  BEGIN
  765.  
  766.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  767.  
  768.                  4.  SYS$QIO
  769.  
  770.                  5.  NUMBER_OF_TARGETS_
  771.  
  772.                  6.  MAX SPEED
  773.  
  774.  
  775. No, number 1 is illegal because Ada identifiers must begin with a letter.
  776. 1HPlease type a space to go on, or B or Q to go back to the question.                                                             1670 158B151Q151$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  777.  
  778.                  2.  BEGIN
  779.  
  780.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  781.  
  782.                  4.  SYS$QIO
  783.  
  784.                  5.  NUMBER_OF_TARGETS_
  785.  
  786.                  6.  MAX SPEED
  787.  
  788.  
  789. No, number 2 is illegal because begin is a reserved word.
  790. 1HPlease type a space to go on, or B or Q to go back to the question.      1761 158B151Q151$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  791.  
  792.                  2.  BEGIN
  793.  
  794.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  795.  
  796.                  4.  SYS$QIO
  797.  
  798.                  5.  NUMBER_OF_TARGETS_
  799.  
  800.                  6.  MAX SPEED
  801.  
  802.  
  803. No, number 4 is illegal because of the dollar sign.  Ada identifiers may
  804. contain only letters, digits, and underlines.
  805. 1HPlease type a space to go on, or B or Q to go back to the question.               1914 158B151Q151$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  806.  
  807.                  2.  BEGIN
  808.  
  809.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  810.  
  811.                  4.  SYS$QIO
  812.  
  813.                  5.  NUMBER_OF_TARGETS_
  814.  
  815.                  6.  MAX SPEED
  816.  
  817.  
  818. No, number 5 is illegal because of the trailing underline.  Every underline
  819. must be followed by a letter or a digit.  You can't have a trailing underline,
  820. and you can't have two underlines together.
  821. 1HPlease type a space to go on, or B or Q to go back to the question.                                                              1755 158B151Q151$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 1.  1553B
  822.  
  823.                  2.  BEGIN
  824.  
  825.                  3.  This_Is_a_Very_Long_Name_for_an_Identifier
  826.  
  827.                  4.  SYS$QIO
  828.  
  829.                  5.  NUMBER_OF_TARGETS_
  830.  
  831.                  6.  MAX SPEED
  832.  
  833.  
  834. No, number 6 is illegal because of the space.  Ada identifiers may contain only
  835. letters, digits, and underlines.
  836. 1HPlease type a space to go on, or B or Q to go back to the question.                     2954 159B151$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    NUMBERS
  837.  
  838. In numbers, unlike identifiers, underlines are not significant.  Thus 12345 and
  839. 12_345 are equivalent.  Spaces aren't permitted within numbers.  When an
  840. underline appears in a number, it must be surrounded by digits.  Thus, all of
  841. these are illegal:     123_     123_.0     _123     12__3
  842.  
  843. Floating point numbers must have at least one digit before and one digit after
  844. the decimal point.  Unlike Basic and Fortran, Ada forces us to write 1.0
  845. instead of 1., and 0.5 instead of .5.  Scientific notation may be used: 1.3E-3
  846. is the same as 0.0013.  Non-negative exponents may be used even in integers:
  847. 12E3 means 12_000.
  848.  
  849. Numbers may be specified in any base from 2 to 16, as shown below.  These three
  850. numbers are all equal:
  851.  
  852.            16#FC03#         2#1111_1100_0000_0011#         8#176003#
  853.  
  854. A number with a base may have an exponent.  The number after the E is still
  855. written in decimal, and gives the power by which the base is raised.  Thus
  856. 2#110#E5 is 6 times 2**5, or 192.
  857. 1HPlease type a space to go on, or B to go back.                      2957 160B158$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       MAKING THE DOT NOTATION AUTOMATIC
  858.  
  859. These two programs are equivalent:
  860.  
  861.       with TEXT_IO;                           with TEXT_IO; use TEXT_IO;
  862.       procedure HELLO is                      procedure HELLO is
  863.       begin                                   begin
  864.          TEXT_IO.PUT_LINE("Hello!");             PUT_LINE("Hello!");
  865.       end HELLO;                              end HELLO;
  866.  
  867. We've said that the statement with TEXT_IO; makes the package visible, so that
  868. our program can call the procedures and functions in it.  To call a procedure,
  869. we write the name of the package, a dot, and the name of the procedure.
  870.  
  871. The statement use TEXT_IO; tells the compiler to supply the name of the package
  872. and the dot for us.  That's why the two programs above are equivalent.
  873.  
  874. Remember, in Ada with provides visibility; use asks the compiler to supply the
  875. package name and the dot.
  876.  
  877. The Ada meanings of the words with and use are more or less reversed from their
  878. meanings in Pascal.  Also, in Ada one can't use records, only packages.
  879. 1HPlease type a space to go on, or B to go back.                   3040 161B159$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      with TEXT_IO;                           with TEXT_IO; use TEXT_IO;
  880.       procedure HELLO is                      procedure HELLO is
  881.       begin                                   begin
  882.          TEXT_IO.PUT_LINE("Hello!");             PUT_LINE("Hello!");
  883.       end HELLO;                              end HELLO;
  884.  
  885. A program can with and use several packages.  For example, there's a package
  886. that comes with Ada called CALENDAR.  Suppose we've also compiled two packages
  887. of our own, called MY_PKG_1 and MY_PKG_2.  Then our program might say
  888.  
  889.                   with TEXT_IO, CALENDAR, MY_PKG_1, MY_PKG_2;
  890.                   use  TEXT_IO, CALENDAR, MY_PKG_1, MY_PKG_2;
  891.  
  892. In this case, when the compiler sees the call to PUT_LINE, it will search all
  893. four packages that we've used for a procedure PUT_LINE that takes one STRING
  894. argument.  If it finds no procedure PUT_LINE, the compiler will print an error
  895. message, like "PUT_LINE is not declared" or "Undeclared identifier PUT_LINE."
  896.  
  897. You may ask, what if there are several procedures PUT_LINE among the four
  898. packages?  Will the compiler stop when it finds the first PUT_LINE?  No.
  899. 1HPlease type a space to go on, or B to go back.                                    2751 162B160$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                  with TEXT_IO, CALENDAR, MY_PKG_1, MY_PKG_2;
  900.                   use  TEXT_IO, CALENDAR, MY_PKG_1, MY_PKG_2;
  901.  
  902. If the compiler finds several PUT_LINEs, the name PUT_LINE is said to be
  903. overloaded.  In that case the compiler will use the number and types of
  904. arguments to try to select the right PUT_LINE.  For example, if TEXT_IO
  905. contains a PUT_LINE that takes one STRING argument, and MY_PKG_1 contains a
  906. PUT_LINE that takes one INTEGER argument, the compiler will write a call to
  907. TEXT_IO.PUT_LINE and not MY_PKG_1.PUT_LINE, because the calling statement
  908. supplies one STRING argument.
  909.  
  910. If there's more than one PUT_LINE that takes exactly one STRING argument, then
  911. the call is ambiguous and the compiler can't resolve the overloading.  The
  912. error message will be something like "Ambiguity detected during overload
  913. resolution" or "Ambiguous expression."  In that case, we'd have to specify
  914. TEXT_IO.PUT_LINE even though we said use TEXT_IO;.
  915. 1HPlease type a space to go on, or B to go back.                         2524 163B161$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In summary, the compiler will search all the packages that we've used for a
  916. procedure with the correct number and types of arguments.  If it finds exactly
  917. one, everything's fine.  If it finds no procedure with the correct name, the
  918. error message will be something like "Undeclared identifier."  If it finds one
  919. or more procedures with the correct name, but none of them has the right number
  920. and types of arguments, it will print an error message like "Inconsistency
  921. detected during overload resolution" or "Unresolvable expression."  Finally, if
  922. it finds more than one procedure with the correct number and types of
  923. arguments, the message is "Ambiguity detected during overload resolution" or
  924. "Ambiguous expression."
  925.  
  926. Overloading may seem like an unnecessary complication at this point, but you'll
  927. see later how very useful it can be.
  928. 1HPlease type a space to go on, or B to go back.                                                    19134164116521663166B162$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Which one of the following would most likely be the cause of the message
  929. "Inconsistency detected during overload resolution"?
  930.  
  931.  
  932.     1.  You tried to use a package that you didn't with.
  933.  
  934.     2.  You misspelled the name of a package in a call using dot notation.
  935.  
  936.     3.  You misspelled the name of a procedure or function in a call.
  937.  
  938.     4.  You called a procedure or function with the wrong number or types of
  939.         arguments.
  940. 1HPlease press 1, 2, 3, or 4, or B to go back.                                                               2020 167B163Q163$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  You tried to use a package that you didn't with.
  941.  
  942.     2.  You misspelled the name of a package in a call using dot notation.
  943.  
  944.     3.  You misspelled the name of a procedure or function in a call.
  945.  
  946.     4.  You called a procedure or function with the wrong number or types of
  947.         arguments.
  948.  
  949.  
  950. You're right!  The message "Inconsistency detected during overload resolution"
  951. usually means that you called a procedure or a function with the wrong number
  952. or types of arguments.
  953. 1HPlease type a space to go on, or B or Q to go back to the question.                                                        1961 167B163Q163$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  You tried to use a package that you didn't with.
  954.  
  955.     2.  You misspelled the name of a package in a call using dot notation.
  956.  
  957.     3.  You misspelled the name of a procedure or function in a call.
  958.  
  959.     4.  You called a procedure or function with the wrong number or types of
  960.         arguments.
  961.  
  962.  
  963. No, for number 1 the message would be something like "This package is not named
  964. in a prior with clause," or "use clause was not expected here."
  965. 1HPlease type a space to go on, or B or Q to go back to the question.               1936 167B163Q163$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  You tried to use a package that you didn't with.
  966.  
  967.     2.  You misspelled the name of a package in a call using dot notation.
  968.  
  969.     3.  You misspelled the name of a procedure or function in a call.
  970.  
  971.     4.  You called a procedure or function with the wrong number or types of
  972.         arguments.
  973.  
  974.  
  975. No, if you misspell the name of a package, procedure, or function, the most
  976. probable error message would be "Undeclared identifier."
  977. 1HPlease type a space to go on, or B or Q to go back to the question.                                        2811 168B163$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              DISPLAYING INTEGERS
  978.  
  979. with TEXT_IO; use TEXT_IO;                           with TEXT_IO; use TEXT_IO;
  980. procedure HELLO is             THIS         THIS     procedure ADD is
  981. begin                       <= IS             IS =>  begin
  982.    PUT_LINE("Hello!");         RIGHT       WRONG        PUT_LINE(2 + 2);
  983. end HELLO;                                           end ADD;
  984.  
  985. Now let's write a program called ADD that adds 2 + 2 and prints the result.
  986. You may think that we could take the HELLO program and substitute 2 + 2 for
  987. "Hello!", but that won't work.  (We never said Ada is easy!)  Why won't it
  988. work?  Because TEXT_IO doesn't have a procedure PUT_LINE that takes an INTEGER
  989. argument.  One correct program is this:
  990.  
  991.         with TEXT_IO; use TEXT_IO;
  992.         procedure ADD is
  993.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  994.         begin
  995.            PUT(2 + 2);
  996.            NEW_LINE;
  997.         end ADD;
  998. 1HPlease type a space to go on, or B to go back.                                                                 3269 169B167$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  999.         procedure ADD is
  1000.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  1001.         begin
  1002.            PUT(2 + 2);
  1003.            NEW_LINE;
  1004.         end ADD;
  1005.  
  1006. __________ TEXT_IO __________  The package TEXT_IO contains procedures for type
  1007. | PUT_LINE for type STRING  |  STRING.  This package is ready-to-use.  However,
  1008. | PUT      for type STRING  |  inside TEXT_IO is another package, INTEGER_IO,
  1009. | GET_LINE for type STRING  |  that's not ready-to-use.  It's called a generic
  1010. | GET      for type STRING  |  package because it has an empty box (<>) in
  1011. | NEW_LINE                  |  place of the type.  We can make a new, ready-to-
  1012. | ...                       |  -use package from INTEGER_IO by giving the type:
  1013. |                           |  package MY_INT_IO is new INTEGER_IO(INTEGER); we
  1014. |  ______ INTEGER_IO ______ |  could have used any name in place of MY_INT_IO.
  1015. |  | PUT for type <>      | |  Note that we've declared our new package locally
  1016. |  | GET for type <>      | |  inside the procedure ADD.  MY_INT_IO now has the
  1017. |  | ...                  | |  same procedures and functions as INTEGER_IO, but
  1018. |  |______________________| |  with the empty box filled in with the type
  1019. |___________________________|  INTEGER, like this:
  1020. 1HPlease type a space to go on, or B to go back.       3222 170B168$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                with TEXT_IO; use TEXT_IO;
  1021. __________ TEXT_IO __________   procedure ADD is
  1022. | PUT_LINE for type STRING  |      package MY_INT_IO is new INTEGER_IO(
  1023. | PUT      for type STRING  |           INTEGER); use MY_INT_IO;
  1024. | GET_LINE for type STRING  |   begin
  1025. | GET      for type STRING  |      PUT(2 + 2);
  1026. | NEW_LINE                  |      NEW_LINE;
  1027. | ...                       |   end ADD;
  1028. |                           |
  1029. |  ______ INTEGER_IO ______ |    ______ MY_INT_IO _______
  1030. |  | PUT for type <>      | |    | PUT for type INTEGER |
  1031. |  | GET for type <>      | |    | GET for type INTEGER |
  1032. |  | ...                  | |    | ...                  |
  1033. |  |______________________| |    |______________________|
  1034. |___________________________|
  1035.  
  1036. Since INTEGER_IO (and therefore MY_INT_IO) doesn't have a PUT_LINE, we call
  1037. MY_INT_IO.PUT and then TEXT_IO.NEW_LINE.  Note that our program says
  1038. use MY_INT_IO; after declaring MY_INT_IO.  When the compiler sees the call
  1039. PUT(2 + 2); it writes code to call MY_INT_IO.PUT rather than TEXT_IO.PUT,
  1040. because MY_INT_IO.PUT takes an argument of type INTEGER.  The compiler then
  1041. finds NEW_LINE in TEXT_IO and writes a call to TEXT_IO.NEW_LINE.
  1042. 1HPlease type a space to go on, or B to go back.                                                      1270F171T172B169$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$True or False?  A program can call INTEGER_IO.PUT.
  1043. 1HPlease press T for true or F for false, or B to go back.      1570 173B170Q170$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!  Since INTEGER_IO is generic, a program can't call its procedures
  1044. and functions.  The program must specify the type and create an instance of
  1045. INTEGER_IO, such as MY_INT_IO.  It can then call PUT in MY_INT_IO.
  1046. 1HPlease type a space to go on, or B or Q to go back to the question.      1556 173B170Q170$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$False.  Since INTEGER_IO is generic, a program can't call its procedures and
  1047. functions.  The program must specify the type and create an instance of
  1048. INTEGER_IO, such as MY_INT_IO.  It can then call PUT in MY_INT_IO.
  1049. 1HPlease type a space to go on, or B or Q to go back to the question.                    3265 174B170$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             GENERIC INSTANTIATION
  1050.  
  1051.                  package MY_INT_IO is new INTEGER_IO(INTEGER);
  1052.  
  1053.               ______ INTEGER_IO ______    ______ MY_INT_IO _______
  1054.               | PUT for type <>      |    | PUT for type INTEGER |
  1055.               | GET for type <>      |    | GET for type INTEGER |
  1056.               | ...                  |    | ...                  |
  1057.               |______________________|    |______________________|
  1058.  
  1059. This process of creating an instance of the generic package INTEGER_IO for the
  1060. type INTEGER is called generic instantiation.  Later in this course we'll
  1061. learn to write our own generic packages, procedures, and functions.  However,
  1062. we wanted to learn, early in the course, how to instantiate an already-written
  1063. generic package in order to display integers.
  1064.  
  1065. But why does Ada make TEXT_IO ready-to-use for STRINGs, while INTEGER_IO is
  1066. generic, and has to be instantiated for INTEGERs?  Because programs normally
  1067. use only one type STRING, but can have several integer types.  Right now, we
  1068. know of only one integer type, the standard INTEGER.  Later we'll learn about
  1069. user-defined types and derived types, and we'll see how there can be several
  1070. integer types.  INTEGER_IO can be instantiated for each of these types.
  1071. 1HPlease type a space to go on, or B to go back.           2434 175B173$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Since INTEGER_IO is often instantiated for the standard INTEGER type, some
  1072. implementations of Ada provide an already-instantiated package for the type
  1073. INTEGER, equivalent to our package MY_INT_IO.  However, an implementation of
  1074. Ada need not supply such a package to meet the Ada standard.  Our program did
  1075. its own instantiation of INTEGER_IO so that it would run on any Ada that meets
  1076. the standard.
  1077.  
  1078. There's another generic package within TEXT_IO called FLOAT_IO.  Input and
  1079. output of floating point numbers is done by instantiating FLOAT_IO for the type
  1080. FLOAT.  As with integers, we'll later learn how there can be several floating
  1081. point types besides the standard FLOAT.
  1082.  
  1083. We're now ready for our first Outside Assignment!  Let's compile and run our
  1084. two sample programs, HELLO and ADD.
  1085. 1HPlease type a space to go on, or B to go back.                                          2936 176B174$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          OUTSIDE ASSIGNMENT 1 - PREPARING TO RUN ADA ON YOUR COMPUTER
  1086.  
  1087. Since these screens disappear, you'll probably want to refer to your printed
  1088. course notes when doing the Outside Assignments.  The first assignment appears
  1089. on page 7.  In this assignment, we'll compile, link, and run our first two
  1090. programs, HELLO and ADD.
  1091.  
  1092. First compile HELLO.ADA, then link, and then execute the program.  The exact
  1093. steps will depend on the Ada compiler you're using.  You'll probably have to
  1094. refer to the documentation that came with your compiler.  Note that some
  1095. implementations of Ada use the term "binding" instead of "linking."  When you
  1096. run the program, it should print Hello! on your screen.
  1097.  
  1098. Then compile ADD.ADA, link, and run the program.
  1099.  
  1100. Note that when we compile, we specify the name of the source file being
  1101. compiled.  Many, but not all, implementations of Ada assume the extension to be
  1102. .ADA if it's not specified.  When we link, we specify the name of the main
  1103. program, which in our examples agrees with the name of the source file.  The
  1104. linking step produces a file which we can execute.
  1105. 1HPlease type a space to go on, or B to go back.                                        2230 177B175$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that, before we can compile an Ada program, we must create our own Ada
  1106. library.  Some implementations of Ada come with a library already created for
  1107. us; others require us to type a command to create a library.  When we compile
  1108. HELLO.ADA and ADD.ADA, the procedures HELLO and ADD are added to our library.
  1109. We'll discuss the Ada library in more detail later.
  1110.  
  1111. If you haven't done so already, please type X to exit ADA-TUTR temporarily,
  1112. read page 7 of your printed course notes, and try the first Outside Assignment.
  1113.  
  1114. When you finish Outside Assignment 1, we'll go on to discuss the Ada library
  1115. and separate compilation of program units.
  1116. 1HPlease type X to exit, a space to go on, or B to go back.                                              1918 178B176$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 1!
  1117.  
  1118. We know this first assignment wasn't very interesting, because the programs
  1119. HELLO.ADA and ADD.ADA were supplied for you.  But we had to be sure we can
  1120. compile, link, and execute Ada programs, so we can do the remaining
  1121. assignments.
  1122.  
  1123. The rest of the Outside Assignments should be more challenging!
  1124.  
  1125. Let's go on to discuss the Ada library and separate compilation of program
  1126. units.
  1127. 1HPlease type a space to go on, or B to go back.                                                          2941 179B177$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                THE ADA LIBRARY
  1128.  
  1129. Why do we have to have our own library before running an Ada compiler, unlike
  1130. other compilers?  Because compilers for other languages simply take source code
  1131. and produce object code.  Ada compilers, however, take source code and a
  1132. library and produce object code and an updated library.  The library remembers
  1133. what we've compiled.
  1134.  
  1135.                                 ________________
  1136.                                |                |
  1137.              Source Code       |  Fortran,      |      Object Code
  1138.        ----------------------->|  Pascal, etc.  |----------------------->
  1139.                                |  Compiler      |
  1140.                                |________________|
  1141.  
  1142.                                 ________________
  1143.              Source Code       |                |      Object Code
  1144.        ----------------------->|  Ada           |----------------------->
  1145.              Ada Library       |  Compiler      |  Updated Ada Library
  1146.        ----------------------->|                |----------------------->
  1147.                                |________________|
  1148. 1HPlease type a space to go on, or B to go back.                                   3526 180B178$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$This gives us the advantage that Ada compilation is separate but dependent.
  1149. Some languages, such as Fortran, offer separate and independent compilation.  A
  1150. Fortran main program and a subroutine can be compiled independently, perhaps a
  1151. month apart.  When the subroutine is compiled, Fortran knows nothing about the
  1152. main program, and vice versa.  An advantage of separate compilation is that we
  1153. can develop our program one piece at a time and compile each piece as it's
  1154. developed.  However, the independent compilation is a disadvantage.  The
  1155. compiler can't check that the number and types of arguments in the call agree
  1156. with the number and types of arguments in the subroutine.  A Fortran main
  1157. program might say CALL SUB(I, J, K), while the subroutine might say
  1158. SUBROUTINE SUB(I, J).  Both of these will compile correctly.  When the program
  1159. is run, however, the results are unpredictable.  The program might simply give
  1160. wrong answers with no warning.
  1161.  
  1162. Other languages, such as early Pascal and many versions of Basic, don't have
  1163. separate compilation at all.  The compiler could check the number and types of
  1164. arguments in a call, because the entire program must be compiled at one time.
  1165. But the advantages of separate compilation are lost.  We can't develop the
  1166. program one piece at a time, compiling each piece as it's developed.  And if we
  1167. make the slightest change in one part of the program, the whole program has to
  1168. be recompiled.
  1169. 1HPlease type a space to go on, or B to go back.                                                  3442 181B179$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Ada gives us the advantages of both systems, because compilation is separate
  1170. but dependent.  We can compile a subprogram today and the calling program next
  1171. month.  (We could also put both into one file and compile them together.)  Each
  1172. compilation unit updates the library when it's compiled.  Thus, when a call to
  1173. a subprogram is encountered, the compiler will check the number and types of
  1174. arguments against the subprogram already in the library.
  1175.  
  1176. We could also write the calling program before the subprogram, because Ada lets
  1177. us compile the subprogram specification separately from its body.  (We'll learn
  1178. more about that later.)  The specification contains the name of the subprogram,
  1179. and the names, number, and types of any arguments.  The specification also
  1180. tells which arguments are inputs, which are outputs, and which are both inputs
  1181. and outputs.  That's all the information the compiler needs to compile calls to
  1182. the subprogram; the body can be supplied later.  When the subprogram body is
  1183. compiled, the compiler will make sure it's consistent with the specification.
  1184.  
  1185. Ada comes with several packages, such as TEXT_IO.  These are already compiled
  1186. and placed into the library.  That's why our programs can say with TEXT_IO; and
  1187. call its procedures and functions.
  1188.  
  1189. Ada libraries are a complication compared to other languages, but they offer
  1190. great advantages in program development.
  1191. 1HPlease type a space to go on, or B to go back.                                  1355T182F183B180$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$True or False?  A procedure specification must be compiled before calls to the
  1192. procedure can be compiled.
  1193. 1HPlease press T for true or F for false, or B to go back.                     1419 184B181Q181$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!  The specification contains all the information the compiler
  1194. needs to compile calls to the procedure.
  1195. 1HPlease type a space to go on, or B or Q to go back to the question.                                                         1453 184B181Q181$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$True.  The compiler needs the information in the specification to compile calls
  1196. to the procedure.  However, the procedure body can be compiled later.
  1197. 1HPlease type a space to go on, or B or Q to go back to the question.                       2853 185B181$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             VARIABLES AND CONSTANTS
  1198.  
  1199.       procedure DECLARATIONS_DEMO is
  1200.          I, J, K : INTEGER;
  1201.          L, M    : INTEGER := 30;
  1202.          F, G    : FLOAT;
  1203.          FACTOR  : constant := 1000;
  1204.       begin
  1205.          J := L + 10;          -- Simple assignment statements.
  1206.          F := 0.0;
  1207.          G := F + L;           -- ILLEGAL.  Can't accidentally mix types.
  1208.          G := F + FLOAT(L);    -- Legal.  Can deliberately convert types.
  1209.          K := INTEGER(F) + L;  -- Legal.
  1210.          FACTOR := 100;        -- ILLEGAL.  Constants can't change.
  1211.       end DECLARATIONS_DEMO;
  1212.  
  1213. This program doesn't do anything except demonstrate Ada declarations.  The
  1214. statement I, J, K : INTEGER; brings three integer variables into existence.
  1215. The next statement creates two more integer variables and initializes both of
  1216. them to 30.  Every time this procedure is called, L and M are brought into
  1217. existence and initialized to 30.  Note that this is different from a Fortran
  1218. DATA statement, which initializes only once at compile time.
  1219. 1HPlease type a space to go on, or B to go back.                       2862 186B184$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      procedure DECLARATIONS_DEMO is
  1220.          I, J, K : INTEGER;
  1221.          L, M    : INTEGER := 30;
  1222.          F, G    : FLOAT;
  1223.          FACTOR  : constant := 1000;
  1224.       begin
  1225.          J := L + 10;          -- Simple assignment statements.
  1226.          F := 0.0;
  1227.          G := F + L;           -- ILLEGAL.  Can't accidentally mix types.
  1228.          G := F + FLOAT(L);    -- Legal.  Can deliberately convert types.
  1229.          K := INTEGER(F) + L;  -- Legal.
  1230.          FACTOR := 100;        -- ILLEGAL.  Constants can't change.
  1231.       end DECLARATIONS_DEMO;
  1232.  
  1233. The statement F, G    : FLOAT; creates two variables of type FLOAT.  The next
  1234. statement names a constant.  Writing FACTOR is then equivalent to writing 1000.
  1235. Unlike variables, constants must be initialized.
  1236.  
  1237. The first two executable statements are simple assignment statements.  The
  1238. symbol := is read "becomes."  In the third executable statement, the compiler
  1239. will reject the expression F + L because Ada doesn't let us accidentally mix a
  1240. FLOAT with an INTEGER.
  1241. 1HPlease type a space to go on, or B to go back.              2951 187B185$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      procedure DECLARATIONS_DEMO is
  1242.          I, J, K : INTEGER;
  1243.          L, M    : INTEGER := 30;
  1244.          F, G    : FLOAT;
  1245.          FACTOR  : constant := 1000;
  1246.       begin
  1247.          J := L + 10;          -- Simple assignment statements.
  1248.          F := 0.0;
  1249.          G := F + L;           -- ILLEGAL.  Can't accidentally mix types.
  1250.          G := F + FLOAT(L);    -- Legal.  Can deliberately convert types.
  1251.          K := INTEGER(F) + L;  -- Legal.
  1252.          FACTOR := 100;        -- ILLEGAL.  Constants can't change.
  1253.       end DECLARATIONS_DEMO;
  1254.  
  1255. However, Ada lets us deliberately mix types.  The statement G := F + FLOAT(L);
  1256. is legal because it converts L from INTEGER to FLOAT, adds it to F which is of
  1257. type FLOAT, and stores the result in G, also of type FLOAT.  Likewise, the next
  1258. statement is legal because it converts F to INTEGER, adds the integer L, and
  1259. stores the result in the integer K.  But note that when a FLOAT is converted to
  1260. INTEGER, it's rounded, not truncated.  The last executable statement is illegal
  1261. because a constant can't appear on the left side of an assignment statement.
  1262. 1HPlease type a space to go on, or B to go back.                         191911882189B186$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  1263.         procedure TRY_ME is
  1264.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  1265.            N : INTEGER := 1;
  1266.         begin
  1267.            PUT(N);
  1268.            NEW_LINE;
  1269.            N := 2;
  1270.         end TRY_ME;
  1271.  
  1272. What number will be displayed the second time procedure TRY_ME is called?
  1273.  
  1274.                         1.  The program will display 1.
  1275.  
  1276.                         2.  The program will display 2.
  1277. 1HPlease press 1 or 2, or B to go back.                                                         1845 190B187Q187$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  1278.         procedure TRY_ME is
  1279.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  1280.            N : INTEGER := 1;
  1281.         begin
  1282.            PUT(N);
  1283.            NEW_LINE;
  1284.            N := 2;
  1285.         end TRY_ME;
  1286.  
  1287. You're right!  N is brought into existence and initialized to 1 each time the
  1288. procedure is called, so 1 will be displayed.
  1289. 1HPlease type a space to go on, or B or Q to go back to the question.                               2027 190B187Q187$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  1290.         procedure TRY_ME is
  1291.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  1292.            N : INTEGER := 1;
  1293.         begin
  1294.            PUT(N);
  1295.            NEW_LINE;
  1296.            N := 2;
  1297.         end TRY_ME;
  1298.  
  1299. No, N is declared locally within TRY_ME.  So N is brought into existence and
  1300. initialized to 1 each time the procedure is called, and the procedure will
  1301. display 1 each time.  Also remember that N goes out of existence when TRY_ME
  1302. returns.
  1303. 1HPlease type a space to go on, or B or Q to go back to the question.                                                 2743 191B187$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               ENUMERATION TYPES
  1304.  
  1305. In Ada we can declare enumeration types, where we enumerate every possible
  1306. value for a type.  For example, if we declare
  1307.  
  1308.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1309.    RC : RAINBOW_COLOR;
  1310.  
  1311. then RC can have any of 7 values.  In the executable region we might write
  1312. RC := RED; and we could also test: if RC = RED then ... end if;.  The
  1313. enumerated values, enclosed in parentheses, must follow the rules for Ada
  1314. identifiers, or they can be single characters enclosed in ' marks (called "tic"
  1315. marks), thus:
  1316.  
  1317.                   type EVEN_DIGIT is ('0', '2', '4', '6', '8');
  1318.  
  1319. It's illegal to write type PROCESSOR is (8086, Z80, 1750A); because two of the
  1320. values aren't legal Ada identifiers.  However, it's OK to mix characters and
  1321. identifiers in the same declaration, thus:
  1322.  
  1323.                      type MIXED is (BIG, SMALL, 'X', '9');
  1324. 1HPlease type a space to go on, or B to go back.                                 2726 192B190$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1325.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1326.    RC : RAINBOW_COLOR;
  1327.    TC : TRAFFIC_LIGHT_COLOR;
  1328.  
  1329. With the above declarations, RC could have any of 7 values, and TC could have
  1330. any of 3 values.  The compiler will have no trouble compiling
  1331.  
  1332.                                    RC := RED;
  1333.                                    TC := RED;
  1334.  
  1335. because it knows that in RC := RED; RED must be the RAINBOW_COLOR if it's
  1336. stored into RC, and in TC := RED; RED must be the TRAFFIC_LIGHT_COLOR if it's
  1337. stored into TC.  The compiler knows that the types across := must always match.
  1338. Naturally, it's illegal to write RC := 2; because of the mixed types.
  1339.  
  1340. Also, if we have a procedure DISPLAY that takes one argument of type
  1341. RAINBOW_COLOR, the compiler could handle DISPLAY(RED); because it knows that
  1342. RED must be the RAINBOW_COLOR to fit the procedure.
  1343. 1HPlease type a space to go on, or B to go back.                                                  3444 193B191$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1344.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1345.  
  1346. However, if we had a procedure DISPLAY that takes one RAINBOW_COLOR and another
  1347. procedure DISPLAY that takes one TRAFFIC_LIGHT_COLOR, then the statement
  1348. DISPLAY(RED); would be ambiguous; the compiler couldn't possibly know which
  1349. DISPLAY to call.  In that case, we could specify the type by writing
  1350. RAINBOW_COLOR'(RED).  This is called qualifying the name RED; note the ' with
  1351. the parentheses.  The call would be DISPLAY(RAINBOW_COLOR'(RED));.  The
  1352. statements DISPLAY(VIOLET); and DISPLAY(AMBER); aren't ambiguous; the compiler
  1353. will figure out which DISPLAY to call in these cases.
  1354.  
  1355. Declaring an enumeration type not only defines equality for objects of that
  1356. type, but also an order for the values.  Thus we can check for <, >, <=, etc.
  1357. For example, if we declare A, B: RAINBOW_COLOR; and later write, in the
  1358. executable region, A := YELLOW; and B := BLUE; then the test if A < B then ...
  1359. will turn out to be TRUE.  YELLOW is considered less than BLUE.
  1360.  
  1361. Input and output of enumeration types can be done by instantiating the generic
  1362. package TEXT_IO.ENUMERATION_IO.  For example:
  1363. with TEXT_IO; use TEXT_IO; ...
  1364. package MY_RAINBOW_IO is new ENUMERATION_IO(RAINBOW_COLOR); use MY_RAINBOW_IO;
  1365. 1HPlease type a space to go on, or B to go back.                                2945 194B192$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$There are two enumeration types built into the Ada language:
  1366.  
  1367.       type BOOLEAN is (FALSE, TRUE);
  1368.  
  1369.       type CHARACTER is ( {nul}, {soh}, {stx}, ... , ' ', '!', '"', ... ,
  1370.                           '0', '1', '2', ... , 'A', 'B', 'C', ... ,
  1371.                           'a', 'b', 'c', ... , {del} );
  1372.  
  1373. Since the above two declarations are built into the Ada language, they
  1374. shouldn't be repeated in your programs.  Note that type BOOLEAN is just an
  1375. enumeration type.  The relational operators ( =><=, etc. ) all return
  1376. results of type BOOLEAN.
  1377.  
  1378. The definition of type CHARACTER can't be completely written out, because there
  1379. are 33 unprintable ASCII characters.  However, the enumeration type CHARACTER
  1380. contains all 128 values, in ASCII character order.  On this screen, we've
  1381. denoted the unprintable characters with names in braces, and we've also used
  1382. "..." for brevity.  Note that even if Ada is run on an EBCDIC machine, it's
  1383. guaranteed that type CHARACTER contains the 128 ASCII characters in ASCII
  1384. character order.
  1385. 1HPlease type a space to go on, or B to go back.                               16664195119621973198B193$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1386.  
  1387.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1388.  
  1389.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1390.  
  1391.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);
  1392.  
  1393.  
  1394. Which one of the above type declarations is legal?
  1395. 1HPlease press 1, 2, 3, or 4, or B to go back.          2119 199B194Q194$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1396.  
  1397.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1398.  
  1399.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1400.  
  1401.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);
  1402.  
  1403.  
  1404. You're right!  Enumeration types can contain single characters between ' marks,
  1405. and Ada identifiers.  Number 1 is illegal because it contains STRINGs, number 2
  1406. because ' marks may enclose only single characters, and number 3 because an Ada
  1407. identifier can't begin with a digit.
  1408. 1HPlease type a space to go on, or B or Q to go back to the question.                                                         1847 199B194Q194$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1409.  
  1410.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1411.  
  1412.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1413.  
  1414.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);
  1415.  
  1416.  
  1417. No, number 1 is illegal because an enumeration type can't contain STRINGs, only
  1418. single characters between ' marks, and Ada identifiers.
  1419. 1HPlease type a space to go on, or B or Q to go back to the question.                             1921 199B194Q194$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1420.  
  1421.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1422.  
  1423.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1424.  
  1425.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);
  1426.  
  1427.  
  1428. No, number 2 is illegal because only single characters may appear between '
  1429. marks.  Enumeration types contain single characters between ' marks, and Ada
  1430. identifiers.
  1431. 1HPlease type a space to go on, or B or Q to go back to the question.                                                       1915 199B194Q194$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.  type COUNT is ("1", "2", "3", "AB", "CD", "EF");
  1432.  
  1433.               2.  type COUNT is ('1', '2', '3', 'AB', 'CD', 'EF');
  1434.  
  1435.               3.  type COUNT is (1, 2, 3, AB, CD, EF);
  1436.  
  1437.               4.  type COUNT is ('1', '2', '3', AB, CD, EF);
  1438.  
  1439.  
  1440. No, number 3 is illegal because an Ada identifier can't begin with a digit.
  1441. Enumeration types can contain only single characters between ' marks, and Ada
  1442. identifiers.
  1443. 1HPlease type a space to go on, or B or Q to go back to the question.                                                             2920 200B194$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    SUBTYPES
  1444.  
  1445. A subtype does not define a new type, but it imposes a range constraint on
  1446. objects of that subtype.  For example,
  1447.  
  1448. subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  1449. D : DAY_SUBTYPE; -- D can have only INTEGER values from 1 to 31.
  1450.  
  1451. type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1452. subtype BRIGHT_COLOR is RAINBOW_COLOR range ORANGE .. GREEN;
  1453. B : BRIGHT_COLOR; -- B can have only RAINBOW_COLOR values from ORANGE to GREEN.
  1454.  
  1455. subtype PROBABILITY is FLOAT range 0.0 .. 1.0;
  1456. P : PROBABILITY; -- P can have only FLOAT values from 0.0 to 1.0.
  1457.  
  1458. Every time the program stores a value into D, B, or P, a check is made to see
  1459. if the value is in range.  If it isn't, the message CONSTRAINT_ERROR is
  1460. printed.  Constraint Errors are usually detected at run time.
  1461.  
  1462. Since subtypes don't define new types, the type of D is INTEGER, the type of B
  1463. is RAINBOW_COLOR, and that of P is FLOAT.  Thus, if we write I : INTEGER; we
  1464. can write D := D + I; etc., because D and I have the same type.
  1465. 1HPlease type a space to go on, or B to go back.                                                        2315 201B199$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We don't have to give the name of the subtype explicitly.  If we declare
  1466.  
  1467.                            D : INTEGER range 1 .. 31;
  1468.  
  1469. the compiler creates its own name for the subtype internally; we never see it.
  1470. This is called an anonymous subtype.  The name the compiler creates will be one
  1471. that we can't accidentally create ourselves.  Perhaps it will contain a control
  1472. character or punctuation mark that Ada doesn't allow us to put into an
  1473. identifier.  The above declaration is equivalent to
  1474.  
  1475.                  subtype (something) is INTEGER range 1 .. 31;
  1476.                  D : (something);
  1477.  
  1478. where (something) represents the anonymous subtype that we can't see or write.
  1479. 1HPlease type a space to go on, or B to go back.                                                             3253 202B200$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               SIMPLE ATTRIBUTES
  1480.  
  1481. An attribute consists of apostrophe (called a "tic" mark for short), and the
  1482. name of the attribute.  Attributes often follow type names.  They're something
  1483. like functions, except that they usually involve a type.  For example:
  1484.  
  1485.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1486.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1487.    RAINBOW_COLOR'SUCC(GREEN)       is BLUE
  1488.    TRAFFIC_LIGHT_COLOR'PRED(GREEN) is AMBER
  1489.  
  1490. The attributes SUCC and PRED stand for successor and predecessor, respectively.
  1491. In RAINBOW_COLORs, the successor of GREEN is BLUE, and in TRAFFIC_LIGHT_COLORs,
  1492. the predecessor of GREEN is AMBER.  Thus we could write R : RAINBOW_COLOR; and
  1493. then R := RAINBOW_COLOR'SUCC(GREEN);.  You'll get a CONSTRAINT_ERROR if you
  1494. try to take the successor of the last item or the predecessor of the first; for
  1495. example, taking RAINBOW_COLOR'PRED(RED) will cause an error.
  1496.  
  1497. SUCC and PRED work with any discrete type.  That means any integer type or
  1498. enumeration type.  These two attributes aren't particularly useful with integer
  1499. types, because we can simply add or subtract 1 instead.  So they're usually
  1500. used with enumeration types.
  1501. 1HPlease type a space to go on, or B to go back.                       3340 203B201$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1502.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1503.  
  1504. The attribute POS converts from a discrete type to an integer, and VAL converts
  1505. from an integer to a discrete type.  Again, the type is usually an enumeration
  1506. type, because there's little point converting from integer to integer.
  1507.  
  1508. For example, RAINBOW_COLOR'POS(ORANGE) is 1.  (The positions are numbered from
  1509. zero.)  RAINBOW_COLOR'POS(RED) is 0 and RAINBOW_COLOR'POS(VIOLET) is 6.
  1510. TRAFFIC_LIGHT_COLOR'POS(GREEN) is 2, but RAINBOW_COLOR'POS(GREEN) is 3.
  1511. CHARACTER'POS('A') is 65, because the ASCII value of 'A' is 65, and the type
  1512. CHARACTER contains all 128 characters in ASCII order.  CHARACTER'POS('0') is
  1513. 48, because the ASCII value of the character '0' is 48.
  1514.  
  1515. VAL converts the other way, so RAINBOW_COLOR'VAL(0) is RED, and
  1516. RAINBOW_COLOR'VAL(6) is VIOLET.  Taking the RAINBOW_COLOR'VAL of an argument
  1517. outside the range 0 .. 6 will raise a CONSTRAINT_ERROR.  CHARACTER'VAL(65) is
  1518. 'A', and CHARACTER'VAL(7) is the "bell" character (control-G).  Since BOOLEAN
  1519. is an enumeration type, BOOLEAN'VAL(0) is FALSE and BOOLEAN'VAL(1) is TRUE.
  1520. 1HPlease type a space to go on, or B to go back.                                    155412042205B202$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  1521.  
  1522.                           What is MONTH_TYPE'POS(FEB)?
  1523.  
  1524.  
  1525.                           1.  MONTH_TYPE'POS(FEB) is 1.
  1526.  
  1527.                           2.  MONTH_TYPE'POS(FEB) is 2.
  1528. 1HPlease press 1 or 2, or B to go back.                      1525 206B203Q203$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  1529.  
  1530. You're right!  The positions are numbered from zero, so FEB is in position 1,
  1531. and MONTH_TYPE'POS(FEB) is 1.
  1532. 1HPlease type a space to go on, or B or Q to go back to the question.                                                   1471 206B203Q203$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  1533.  
  1534. No, the positions are numbered from zero, so FEB is in position 1, and
  1535. MONTH_TYPE'POS(FEB) is 1.
  1536. 1HPlease type a space to go on, or B or Q to go back to the question.     2730 207B203$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$While POS and VAL convert to and from integers, the attributes IMAGE and VALUE
  1537. convert to and from STRINGs.  They work with any discrete types, and are useful
  1538. with integer types as well as enumeration types.  For example,
  1539.  
  1540.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1541.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1542.  
  1543.    RAINBOW_COLOR'VALUE("RED")       is RED
  1544.    RAINBOW_COLOR'VALUE("yellow")    is YELLOW
  1545.    TRAFFIC_LIGHT_COLOR'IMAGE(AMBER) is "AMBER"
  1546.  
  1547.    INTEGER'VALUE("123") is  123
  1548.    INTEGER'IMAGE(123)   is " 123"
  1549.    INTEGER'IMAGE(-123)  is "-123"
  1550.  
  1551. VALUE will raise a CONSTRAINT_ERROR if the STRING can't be converted to the
  1552. discrete type.  For example, taking RAINBOW_COLOR'VALUE("CHARTREUSE") or
  1553. INTEGER'VALUE("12X3") will normally print CONSTRAINT_ERROR on the terminal and
  1554. stop the program.
  1555. 1HPlease type a space to go on, or B to go back.                                              3058 208B206$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$For any discrete type, the attributes FIRST and LAST are also available.
  1556.  
  1557.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  1558.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  1559.    RAINBOW_COLOR'FIRST      is RED
  1560.    TRAFFIC_LIGHT_COLOR'LAST is GREEN
  1561.  
  1562. A program can use these attributes with INTEGER to determine the size of
  1563. integers on the host computer.  For example, if your PC Ada has 16-bit 2's
  1564. complement integers, while a mainframe Ada uses 32-bit 2's complement, then
  1565.  
  1566.     INTEGER'FIRST is -32_768 on your PC and -2_147_483_648 on the mainframe.
  1567.     INTEGER'LAST  is  32_767 on your PC and  2_147_483_647 on the mainframe.
  1568.  
  1569. Most attributes can also be used with subtypes:
  1570.                  subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  1571.                  DAY_SUBTYPE'FIRST is 1
  1572.                  DAY_SUBTYPE'LAST  is 31
  1573.  
  1574. There are two subtype definitions involving LAST built into the Ada language:
  1575.               subtype POSITIVE is INTEGER range 1 .. INTEGER'LAST;
  1576.               subtype NATURAL  is INTEGER range 0 .. INTEGER'LAST;
  1577. 1HPlease type a space to go on, or B to go back.                  2911 209B207$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$More attributes are discussed in the Advanced Topics section.  In summary,
  1578. discrete type means any integer or enumeration type.  (The only integer type
  1579. we've learned about so far is the standard INTEGER.)
  1580.  
  1581.        POS converts from a discrete type to an integer.
  1582.        VAL converts from an integer to a discrete type.
  1583.        IMAGE converts from a discrete type to STRING.
  1584.        VALUE converts from STRING to a discrete type.
  1585.        FIRST and LAST take no argument and give a discrete type.
  1586.        SUCC and PRED take a discrete type and give the same discrete type.
  1587.  
  1588.  
  1589.        Also remember that a type name followed by ' denotes an attribute:
  1590.                          PUT(CHARACTER'VAL(7)); -- beep
  1591.  
  1592.                 A type name followed by ( ) denotes conversion:
  1593.                                G := F + FLOAT(I);
  1594.  
  1595.             And a type name followed by '( ) denotes qualification:
  1596.                           DISPLAY(RAINBOW_COLOR'(RED));
  1597. 1HPlease type a space to go on, or B to go back.                                                                 184282101211221232114213521462147215B208$$$$$$$$$$$$$$$$$$$$$$$$          1.  RAINBOW_COLOR'FIRST             5.  RAINBOW_COLOR'PRED
  1598.  
  1599.           2.  RAINBOW_COLOR'IMAGE             6.  RAINBOW_COLOR'SUCC
  1600.  
  1601.           3.  RAINBOW_COLOR'LAST              7.  RAINBOW_COLOR'VAL
  1602.  
  1603.           4.  RAINBOW_COLOR'POS               8.  RAINBOW_COLOR'VALUE
  1604.  
  1605.  
  1606. Which one of the above attributes would you use to convert from the STRING
  1607. "Blue" to the RAINBOW_COLOR BLUE?
  1608. 1HPlease press 1, 2, 3, 4, 5, 6, 7, or 8, or B to go back.                                  1461 216B209Q209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!  The attribute VALUE converts from STRING to a discrete type.
  1609.  
  1610.                       RAINBOW_COLOR'VALUE("Blue") is BLUE.
  1611. 1HPlease type a space to go on, or B or Q to go back to the question.               1613 216B209Q209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, FIRST and LAST take no argument and return a discrete type:
  1612.  
  1613.           RAINBOW_COLOR'FIRST is RED and RAINBOW_COLOR'LAST is VIOLET.
  1614.  
  1615. You want to convert from a STRING argument to a discrete type.
  1616. 1HPlease type a space to go on, or B or Q to go back to the question.                                                               1520 216B209Q209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, IMAGE converts from a discrete type to STRING:
  1617.  
  1618.                       RAINBOW_COLOR'IMAGE(BLUE) is "BLUE".
  1619.  
  1620. You want to convert from STRING to a discrete type.
  1621. 1HPlease type a space to go on, or B or Q to go back to the question.                                                        1518 216B209Q209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, POS converts from a discrete type to an integer:
  1622.  
  1623.                          RAINBOW_COLOR'POS(BLUE) is 4.
  1624.  
  1625. You want to convert from STRING to a discrete type.
  1626. 1HPlease type a space to go on, or B or Q to go back to the question.                                                          1628 216B209Q209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, PRED and SUCC take a discrete type argument and return the same discrete
  1627. type.
  1628.  
  1629.    RAINBOW_COLOR'PRED(BLUE) is GREEN and RAINBOW_COLOR'SUCC(BLUE) is INDIGO.
  1630.  
  1631. You want to convert from STRING to a discrete type.
  1632. 1HPlease type a space to go on, or B or Q to go back to the question.                                                1518 216B209Q209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$No, VAL converts from an integer to a discrete type.
  1633.  
  1634.                          RAINBOW_COLOR'VAL(4) is BLUE.
  1635.  
  1636. You want to convert from STRING to a discrete type.
  1637. 1HPlease type a space to go on, or B or Q to go back to the question.                                                          3322 217B209$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   OPERATORS
  1638.  
  1639. The four basic arithmetic operators, +-*, and /, can be used with any
  1640. integer or floating point type.  (We'll learn about fixed point types in the
  1641. Advanced Topics section.)  The exponentiation operator, **, takes a base of
  1642. type INTEGER or FLOAT, and an exponent of type INTEGER.  It returns the same
  1643. type as the base.  Note that FLOAT ** FLOAT doesn't come with Ada.  Of course,
  1644. a vendor may supply a math package with his Ada compiler to increase its sales
  1645. appeal.  If the math package includes a function "**" to raise a FLOAT base to
  1646. a FLOAT exponent, then our programs can with and use the package and then use
  1647. ** between two FLOATs.  (Similarly, EXP, LOG, and the trig functions don't
  1648. come with Ada, but the vendor may supply them in a math package.)
  1649.  
  1650. The six relational operators are:
  1651.  
  1652. <  less than                  >  greater than                  =  equal to
  1653.  
  1654. <= less than or equal to      >= greater than or equal to      /= not equal to
  1655.  
  1656. Five of these are the same as in Basic and Pascal, but the Ada symbol for "not
  1657. equal to" is /=, because <> means box.  The relational operators compare two
  1658. objects of the same type, and return a result of type BOOLEAN.
  1659. 1HPlease type a space to go on, or B to go back.                                                      3439 218B216$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$All of the above operators are used between two objects (e.g., B := A + B;).
  1660. Of course, + and - may also be unary operators (B := +A;  A := -A;).
  1661.  
  1662. The operators andor, and xor are used between two BOOLEAN objects, and not is
  1663. a unary BOOLEAN operator.  Naturally, xor is the exclusive or:  A xor B is TRUE
  1664. if either A or B is TRUE, but not if both are TRUE.
  1665.  
  1666. The numeric operator abs takes the absolute value of an INTEGER or FLOAT.
  1667. Since abs is a unary operator like -, we can write B := abs A;.  We may, but
  1668. don't have to, write B := abs(A);.
  1669.  
  1670. When used between two integers, / gives only the integer part of the quotient.
  1671. Thus 9/4 is 2.  The operators mod (modulo) and rem (remainder) are very similar
  1672. to each other, and are used between two integers to give only the remainder in
  1673. division.  For example, 9 mod 4 is 1.  For positive arguments, mod and rem are
  1674. the same.  But with negative arguments, mod gives the sign of the denominator
  1675. while rem gives the sign of the numerator.  Many programmers simply ignore rem
  1676. and use mod exclusively.
  1677.  
  1678. The operator & concatenates arrays, so we'll discuss it later.  We'll learn
  1679. that a STRING is one type of array (an array of CHARACTERs), so & can
  1680. concatenate STRINGs.
  1681. 1HPlease type a space to go on, or B to go back.                                     2325 219B217$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  RANGE TESTS
  1682.  
  1683. The reserved word in tests if something is inside a range, and returns a
  1684. BOOLEAN result.  For example, if LOWER, UPPER, and X are declared as FLOATs, we
  1685. need not write
  1686.  
  1687.                      if X >= LOWER and X <= UPPER then ...
  1688.  
  1689. This can be expressed more clearly as
  1690.  
  1691.                         if X in LOWER .. UPPER then ...
  1692.  
  1693. We can also write not in.  Thus X not in LOWER .. UPPER is a clear way of
  1694. expressing X < LOWER or X > UPPER.
  1695.  
  1696. A subtype may be substituted for the range to the right of in.  If DAY_SUBTYPE
  1697. is defined as a subtype of INTEGER, and D is an INTEGER, then we can write
  1698. D in DAY_SUBTYPE.
  1699. 1HPlease type a space to go on, or B to go back.                                                   1728122022213222B218$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If we have the following declarations:
  1700.  
  1701.                              B       : BOOLEAN;
  1702.                              A, X, Y : CHARACTER;
  1703.  
  1704. then which one of the following is illegal?
  1705.  
  1706.                        1.    B := X <> Y;
  1707.  
  1708.                        2.    B := A in X .. Y;
  1709.  
  1710.                        3.    B := A = X and X = Y;
  1711. 1HPlease press 1, 2, or 3, or B to go back.                                                1746 223B219Q219$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             B       : BOOLEAN;
  1712.                              A, X, Y : CHARACTER;
  1713.  
  1714.  
  1715.                        1.    B := X <> Y;
  1716.  
  1717.                        2.    B := A in X .. Y;
  1718.  
  1719.                        3.    B := A = X and X = Y;
  1720.  
  1721.  
  1722. You're right!  Number 1 is illegal because <> should be /=.
  1723. 1HPlease type a space to go on, or B or Q to go back to the question.                              1845 223B219Q219$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             B       : BOOLEAN;
  1724.                              A, X, Y : CHARACTER;
  1725.  
  1726.  
  1727.                        1.    B := X <> Y;
  1728.  
  1729.                        2.    B := A in X .. Y;
  1730.  
  1731.                        3.    B := A = X and X = Y;
  1732.  
  1733.  
  1734. No, number 2 is legal.  The reserved word in tests to see if A is within the
  1735. range X to Y.  It returns a BOOLEAN result, which is stored in B.
  1736. 1HPlease type a space to go on, or B or Q to go back to the question.                               2137 223B219Q219$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             B       : BOOLEAN;
  1737.                              A, X, Y : FLOAT;
  1738.  
  1739.  
  1740.                        1.    B := X <> Y;
  1741.  
  1742.                        2.    B := A in X .. Y;
  1743.  
  1744.                        3.    B := A = X and X = Y;
  1745.  
  1746.  
  1747. No, number 3 is legal.  Parentheses aren't necessary here, but it's the same as
  1748. if we had written
  1749.  
  1750.                            B := (A = X) and (X = Y);
  1751.  
  1752. In two places = returns a BOOLEAN result.  Then and takes the two BOOLEAN
  1753. results and also returns a result of type BOOLEAN.  That final result is then
  1754. stored in B.
  1755. 1HPlease type a space to go on, or B or Q to go back to the question.                                       2667 224B219$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            THE SHORT CIRCUIT FORMS
  1756.  
  1757. Suppose that N (for numerator) and D (for denominator) are FLOATs, and we want
  1758. to execute a block of code if the quotient is 10.0 or greater.  We could write
  1759.  
  1760.                            if N/D >= 10.0 then
  1761.                               -----;
  1762.                               -----;  (block of code)
  1763.                               -----;
  1764.                            end if;
  1765.  
  1766. However, we realize that if D is 0.0, the program will raise a NUMERIC_ERROR
  1767. trying to compute N/D.  If the denominator is zero, we consider the quotient to
  1768. be very large, so we want to execute the block of code when D is zero.  Our
  1769. second attempt might be
  1770.  
  1771.                          if D = 0.0 or N/D >= 10.0 then
  1772.                             -----;
  1773.                             -----;  (block of code)
  1774.                             -----;
  1775.                          end if;
  1776. 1HPlease type a space to go on, or B to go back.         2873 225B223$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         if D = 0.0 or N/D >= 10.0 then
  1777.                             -----;
  1778.                             -----;  (block of code)
  1779.                             -----;
  1780.                          end if;
  1781.  
  1782. Here we hope that N/D won't be evaluated if D is zero.  We figure that the
  1783. compiler should be smart enough to know that if the expression before or is
  1784. TRUE, then the whole expression must be TRUE, so the expression to the right of
  1785. or needn't be evaluated.  However, there's no guarantee that the compiler will
  1786. write code to skip the evaluation of the second expression when the first is
  1787. TRUE.  An optimizing compiler just might, for some unknown reason, even decide
  1788. that the expression on the right should be evaluated first.
  1789.  
  1790. However, Ada has a "short circuit" form called or else, that looks like this:
  1791.  
  1792.                       if D = 0.0 or else N/D >= 10.0 then
  1793.                          -----;
  1794.                          -----;  (block of code)
  1795.                          -----;
  1796.                       end if;
  1797. 1HPlease type a space to go on, or B to go back.   3330 226B224$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      if D = 0.0 or else N/D >= 10.0 then
  1798.                          -----;
  1799.                          -----;  (block of code)
  1800.                          -----;
  1801.                       end if;
  1802.  
  1803. Ada guarantees that the expression to the left of or else will be evaluated
  1804. first.  If this expression is TRUE, the entire expression must be TRUE, and
  1805. it's guaranteed that the second expression won't be evaluated.  If the first
  1806. expression is FALSE, then of course the second expression must be evaluated to
  1807. determine if the entire expression is TRUE.  Note that the code above will
  1808. never try to divide by zero.  If D is zero, the expression on the left is TRUE.
  1809. The expression on the right won't be evaluated in that case.
  1810.  
  1811. There's another "short circuit" form called and then.  If the expression to
  1812. the left of and then is FALSE, the whole expression must be FALSE, and the
  1813. expression on the right won't be evaluated.  If the expression on the left is
  1814. TRUE, then the expression on the right must be evaluated to determine the value
  1815. of the entire expression.  Suppose this time that we want to execute a block of
  1816. code if N/D is less than 10.0.  If the denominator is zero, we consider the
  1817. quotient to be very large, and we don't want to execute the block of code in
  1818. that case.  We can write the following:
  1819. 1HPlease type a space to go on, or B to go back.                                              2639 227B225$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      if D /= 0.0 and then N/D < 10.0 then
  1820.                          -----;
  1821.                          -----;  (block of code)
  1822.                          -----;
  1823.                       end if;
  1824.  
  1825. Again this protects us from trying to divide by zero.  If D is zero, the
  1826. expression on the left is FALSE.  The second expression won't be evaluated in
  1827. that case.
  1828.  
  1829. Don't use the short circuit forms where the standard and and or will do.  The
  1830. short circuit forms prevent certain compiler optimizations by requiring the
  1831. expression on the left to be evaluated first.
  1832.  
  1833. After we discuss arrays, we'll see how the short circuit forms can prevent us
  1834. from using out-of-range subscripts.  And when we learn about access types,
  1835. we'll see how the short circuit forms can keep us from dereferencing a null
  1836. pointer.  That means trying to access "the object pointed to" when there's no
  1837. such object.
  1838. 1HPlease type a space to go on, or B to go back.                                     184912282229B226$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Assume that N has been declared FLOAT, and that our program withs and uses a
  1839. math package with a square root function called SQRT.  Naturally, we don't want
  1840. to call SQRT with a negative argument.  Which of the following would be more
  1841. appropriate?
  1842.  
  1843.  
  1844.            1.    if N >= 0.0 and then SQRT(N) > 1.618 then ...
  1845.  
  1846.            2.    if N >= 0.0 or else  SQRT(N) > 1.618 then ...
  1847. 1HPlease press 1 or 2, or B to go back.                           1644 230B227Q227$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           1.    if N >= 0.0 and then SQRT(N) > 1.618 then ...
  1848.  
  1849.            2.    if N >= 0.0 or else  SQRT(N) > 1.618 then ...
  1850.  
  1851.  
  1852. You're right!  We don't want the second expression to be evaluated if the first
  1853. expression is FALSE, so we use and then.
  1854. 1HPlease type a space to go on, or B or Q to go back to the question.                                2055 230B227Q227$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           1.    if N >= 0.0 and then SQRT(N) > 1.618 then ...
  1855.  
  1856.            2.    if N >= 0.0 or else  SQRT(N) > 1.618 then ...
  1857.  
  1858.  
  1859. No, we don't want the second expression to be evaluated if the first expression
  1860. is FALSE.  The form or else bypasses the evaluation of the second expression
  1861. when the first expression is TRUE.  Note that if A is true, we know the value
  1862. of A or B without evaluating B.  Using or else in place of or guarantees that B
  1863. won't be evaluated when A is TRUE.
  1864. 1HPlease type a space to go on, or B or Q to go back to the question.                     2841 231B227$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               CONTROL CONSTRUCTS
  1865.  
  1866. You're almost ready to write your own Ada program in an Outside Assignment, but
  1867. first we need to discuss the control constructs.
  1868.  
  1869. Ada encourages structured programming by providing control constructs such as
  1870.  
  1871.                          block ifs with elsifs and else
  1872.                          while loops
  1873.                          for loops
  1874.                          case statements
  1875.  
  1876. Ada also provides a goto statement, but it's seldom if ever needed.  That's
  1877. because the constructs above handle the flow of control more clearly, making
  1878. the program easier to read.  With the constructs above, we know how control
  1879. reaches each statement.  When gotos are used, there can be many paths to a
  1880. statement, and we're not sure how control got there.
  1881.  
  1882. Let's look at the above control constructs, and the goto statement, one at a
  1883. time.  Discussion of the declare statement and Ada "blocks" is postponed until
  1884. we cover exception handlers.
  1885. 1HPlease type a space to go on, or B to go back.                                   3256 232B230$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                 THE "IF" BLOCK
  1886.  
  1887.                           if A >= B and C = A + D then
  1888.                              -----;
  1889.                              -----;  (block of code)
  1890.                              -----;
  1891.                           end if;
  1892.  
  1893. In Ada, every if introduces a block of code that ends with end if;.  There are
  1894. no exceptions; every if always has an end if;.  The condition is followed by
  1895. then, and it can be any expression with a BOOLEAN result.  The above example
  1896. is valid if A, B, C, and D are suitably declared.  Note that each statement in
  1897. the block of code, including the last, has a semicolon.  Note also that end if;
  1898. is two reserved words, so there must be at least one space between them.  All
  1899. Ada control constructs, including if blocks, can be nested to any depth.
  1900.  
  1901. In Pascal, if is designed to execute only one statement conditionally.  If
  1902. there's a whole block of statements to be executed conditionally, it has to be
  1903. enclosed with "begin ... end" so it will be considered as one statement.  In
  1904. Ada, however, if always starts a block of code, so "begin ... end" isn't
  1905. necessary.  The end of the block is always marked by end if; even if there's
  1906. just one statement in the block.
  1907. 1HPlease type a space to go on, or B to go back.                    3152 233B231$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          if A >= B and C = A + D then
  1908.                              -----;
  1909.                              -----;
  1910.                              -----;
  1911.                           elsif G = H + P then
  1912.                              -----;
  1913.                           elsif Q > R or S <= T then
  1914.                              -----;
  1915.                              -----;
  1916.                           else
  1917.                              -----;
  1918.                           end if;
  1919.  
  1920. The reserved words elsif and else are also available; note the unusual spelling
  1921. of elsif.  In the above example, only one of the four blocks of code will be
  1922. executed.  If A >= B and C = A + D is TRUE, the first block of code will be
  1923. executed and the remaining tests and blocks will be skipped.  Control will
  1924. continue after the end if;.  If A >= B and C = A + D is FALSE, then G = H + P
  1925. will be tested.  If it's TRUE, the second block, and only that block, will be
  1926. executed; otherwise, Q > R or S <= T will be tested.  If that's TRUE, the third
  1927. block will be executed; otherwise the else block will be executed.  If all the
  1928. tests are FALSE and there's no else block, then no blocks are executed.
  1929. 1HPlease type a space to go on, or B to go back.                        3423 234B232$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$if A >= B and C = A + D then                      if A >= B and C = A + D then
  1930.    -----;                                            -----;
  1931.    -----;                                            -----;
  1932.    -----;                          THESE             -----;
  1933. elsif G = H + P then          <=    TWO    =>     else
  1934.    -----;                           ARE              if G = H + P then
  1935. elsif Q > R or S <= T then      EQUIVALENT!             -----;
  1936.    -----;                                            else
  1937.    -----;                                               if Q > R or S <= T then
  1938. else                                                       -----;
  1939.    -----;                                                  -----;
  1940. end if;                                                 else
  1941.                                                            -----;
  1942.                                                         end if;
  1943.                                                      end if;
  1944.                                                   end if;
  1945.  
  1946. As shown, elsif is equivalent to else plus if ... end if;.  Although the two
  1947. program segments above are equivalent, the one on the left is much clearer.
  1948. The example on the left doesn't require multiple end if;s at the bottom, and
  1949. the indentation emphasizes that only one of the four blocks of code will be
  1950. executed.
  1951. 1HPlease type a space to go on, or B to go back.                                                     244222351236323742385239B233$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  1952.                               ...
  1953.                               if D = 0 then
  1954.                                  ONE;
  1955.                               elsif N/D = 1 then
  1956.                                  TWO;
  1957.                               elsif D = 1 then
  1958.                                  THREE;
  1959.                               else
  1960.                                  FOUR;
  1961.                               end if;
  1962.  
  1963. In this segment of code, which procedure(s) will be called?
  1964.  
  1965.                   1.  Procedure ONE will be called.
  1966.                   2.  Procedure TWO will be called.
  1967.                   3.  Procedure THREE will be called.
  1968.                   4.  Procedure FOUR will be called.
  1969.                   5.  Procedures TWO and THREE will be called.
  1970. 1HPlease press 1, 2, 3, 4, or 5, or B to go back.                                  2311 240B234Q234$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  1971.                               ...
  1972.                               if D = 0 then
  1973.                                  ONE;
  1974.                               elsif N/D = 1 then
  1975.                                  TWO;
  1976.                               elsif D = 1 then
  1977.                                  THREE;
  1978.                               else
  1979.                                  FOUR;
  1980.                               end if;
  1981.  
  1982. You're right!  The first test, D = 0, is FALSE, so the second test is made.
  1983. N/D = 1 is TRUE, so TWO is called.  Since only one block of code is executed in
  1984. an if block, the remaining tests are not done.
  1985. 1HPlease type a space to go on, or B or Q to go back to the question.                                                                 2230 240B234Q234$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  1986.                               ...
  1987.                               if D = 0 then
  1988.                                  ONE;
  1989.                               elsif N/D = 1 then
  1990.                                  TWO;
  1991.                               elsif D = 1 then
  1992.                                  THREE;
  1993.                               else
  1994.                                  FOUR;
  1995.                               end if;
  1996.  
  1997. No, both D and N are initialized to 1, so the first test, D = 0, is FALSE and
  1998. the second test is made.  The block that's executed is the first block
  1999. following a test that's TRUE.
  2000. 1HPlease type a space to go on, or B or Q to go back to the question.                                              2413 240B234Q234$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  2001.                               ...
  2002.                               if D = 0 then
  2003.                                  ONE;
  2004.                               elsif N/D = 1 then
  2005.                                  TWO;
  2006.                               elsif D = 1 then
  2007.                                  THREE;
  2008.                               else
  2009.                                  FOUR;
  2010.                               end if;
  2011.  
  2012. No, both D and N are initialized to 1, so the second test, N/D = 1, is TRUE.
  2013. The block that's executed is the first block following a test that's TRUE.
  2014. Once a block is executed, no further tests in that if block are made.  Thus,
  2015. THREE isn't called even though D = 1 is TRUE.
  2016. 1HPlease type a space to go on, or B or Q to go back to the question.                                                               2271 240B234Q234$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  2017.                               ...
  2018.                               if D = 0 then
  2019.                                  ONE;
  2020.                               elsif N/D = 1 then
  2021.                                  TWO;
  2022.                               elsif D = 1 then
  2023.                                  THREE;
  2024.                               else
  2025.                                  FOUR;
  2026.                               end if;
  2027.  
  2028. No, both D and N are initialized to 1, so the second test, N/D = 1, is TRUE.
  2029. The block that's executed is the first block following a test that's TRUE.  The
  2030. else block is executed only if all the tests are FALSE.
  2031. 1HPlease type a space to go on, or B or Q to go back to the question.     2245 240B234Q234$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              D, N : INTEGER := 1;
  2032.                               ...
  2033.                               if D = 0 then
  2034.                                  ONE;
  2035.                               elsif N/D = 1 then
  2036.                                  TWO;
  2037.                               elsif D = 1 then
  2038.                                  THREE;
  2039.                               else
  2040.                                  FOUR;
  2041.                               end if;
  2042.  
  2043. No, although N/D = 1 and D = 1 are both TRUE, only one block of code in an if
  2044. block is executed.  The block that's executed is the first block following a
  2045. test that's TRUE.
  2046. 1HPlease type a space to go on, or B or Q to go back to the question.                               2512 241B234$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                 "WHILE" LOOPS
  2047.  
  2048.                                while I < 10 loop
  2049.                                   -----;
  2050.                                   -----;
  2051.                                   -----;
  2052.                                end loop;
  2053.  
  2054. The while loop first evaluates the BOOLEAN expression (I < 10 in this example).
  2055. If it's FALSE, the block of code isn't executed at all, and execution continues
  2056. after the end loop;.  If it's TRUE, the block of code is executed and then the
  2057. BOOLEAN condition is again evaluated.  If the condition is still TRUE, the
  2058. block is executed again and the BOOLEAN expression is evaluated again, and so
  2059. forth.  When the BOOLEAN expression becomes FALSE, the block of code is skipped
  2060. and execution continues after the end loop;.
  2061. 1HPlease type a space to go on, or B to go back.                                                                2120 242B240$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$To create an "infinite loop," it isn't necessary to write while TRUE loop.  We
  2062. simply write loop, as follows:
  2063.  
  2064.                                    loop
  2065.                                       -----;
  2066.                                       -----;
  2067.                                       -----;
  2068.                                    end loop;
  2069.  
  2070. Ada doesn't have a "repeat ... until" loop, with the test at the bottom.
  2071. However, we can create a loop that's equivalent to a "repeat ... until" loop by
  2072. using an infinite loop with an exit statement, to be covered later.
  2073.  
  2074. 1HPlease type a space to go on, or B to go back.                                                        3273 243B241$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   "FOR" LOOPS
  2075.  
  2076.          for IX in 1 .. 10 loop         for IX in reverse 1 .. 10 loop
  2077.             -----;                         -----;
  2078.             -----;                         -----;
  2079.          end loop;                      end loop;
  2080.  
  2081. Here are two sample for loops.  We need not declare the index (IX in these
  2082. examples) in the declarative region of the program; an index of a for loop
  2083. declares itself.  In these examples, IX comes into existence at the for
  2084. statement and goes out of existence at end loop; the index isn't available
  2085. outside the loop.  If the name IX happens to be used in the declarative region,
  2086. it's a different IX.  Inside the loop IX refers to the index; there the name IX
  2087. is said to hide any IX that might be mentioned in the declarative region.
  2088.  
  2089. The index variable may not be modified.  In these examples, IX may not appear
  2090. on the left side of an assignment statement, etc.
  2091.  
  2092. In the first example above, the block of statements is executed ten times, with
  2093. IX equal to 1, then 2, then 3, etc., up to 10.  In the second example, IX
  2094. starts at 10 and counts down to 1.  Note that the range is still written
  2095. 1 .. 10, but the keyword reverse precedes the range.
  2096. 1HPlease type a space to go on, or B to go back.   3345 244B242$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The index of a for loop can have any discrete type (integer or enumeration
  2097. type).  It can't be of type FLOAT.  For example, if we write
  2098.  
  2099.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2100.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2101.  
  2102. then we can write for IX in RED .. BLUE loop, and the compiler will know that
  2103. IX must be of type RAINBOW_COLOR.  Similarly, the type of IX will be
  2104. TRAFFIC_LIGHT_COLOR if we write for IX in RED .. AMBER loop.  But the compiler
  2105. can't handle for IX in RED .. GREEN loop because of the ambiguity.  In this
  2106. case we have to specify the type.  For example, we could write either of these:
  2107.                   for IX in RAINBOW_COLOR'(RED) .. GREEN loop
  2108.                 for IX in RAINBOW_COLOR range RED .. GREEN loop
  2109.  
  2110. Because the index can have any discrete type, there's no STEP clause in Ada.
  2111. One might increment an INTEGER index by 2, but we couldn't add 2 to RED.  For
  2112. uniformity, no STEP clause is available, even if the index type is INTEGER.
  2113.  
  2114. Ranges may contain expressions.  If A, B, C, and D are INTEGER variables, we
  2115. can say for I in A + B .. C + D loop or for I in reverse A + B .. C + D loop.
  2116. In both cases the range is null if C + D is less than A + B.  That won't cause
  2117. an error; the loop is simply skipped when the range is null.
  2118. 1HPlease type a space to go on, or B to go back.                               1713224512463247B243$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If we have
  2119.  
  2120.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2121.    J : INTEGER := 5;
  2122.  
  2123. which one of these statements is illegal?
  2124.  
  2125.  
  2126.                         1.  for I in -J .. J loop
  2127.  
  2128.                         2.  for I in J .. VIOLET loop
  2129.  
  2130.                         3.  for I in VIOLET .. RED loop
  2131. 1HPlease press 1, 2, or 3, or B to go back.                                                               1845 248B244Q244$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2132.    J : INTEGER := 5;
  2133.  
  2134.                         1.  for I in -J .. J loop
  2135.  
  2136.                         2.  for I in J .. VIOLET loop
  2137.  
  2138.                         3.  for I in VIOLET .. RED loop
  2139.  
  2140.  
  2141. You're right!  Number 2 is illegal because the expressions before and after the
  2142. ".." must be of the same type.
  2143. 1HPlease type a space to go on, or B or Q to go back to the question.                               1872 248B244Q244$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2144.    J : INTEGER := 5;
  2145.  
  2146.                         1.  for I in -J .. J loop
  2147.  
  2148.                         2.  for I in J .. VIOLET loop
  2149.  
  2150.                         3.  for I in VIOLET .. RED loop
  2151.  
  2152.  
  2153. No, number 1 is legal.  The expressions on both sides of .. have the same type.
  2154. I will be of type INTEGER and will take 11 values, from -5 to 5.
  2155. 1HPlease type a space to go on, or B or Q to go back to the question.    2147 248B244Q244$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2156.    J : INTEGER := 5;
  2157.  
  2158.                         1.  for I in -J .. J loop
  2159.  
  2160.                         2.  for I in J .. VIOLET loop
  2161.  
  2162.                         3.  for I in VIOLET .. RED loop
  2163.  
  2164.  
  2165. No, number 3 is legal.  The expressions on both sides of .. have the same type.
  2166. The loop will be skipped because RED is less than VIOLET, giving a null range.
  2167. But the syntax is legal.  To make I start at VIOLET and count down to RED, we
  2168. would write
  2169.  
  2170.                       for I in reverse RED .. VIOLET loop
  2171. 1HPlease type a space to go on, or B or Q to go back to the question.                             3133 249B244$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              THE "EXIT" STATEMENT
  2172.  
  2173.          for I in 1 .. 10 loop            for I in 1 .. 10 loop
  2174.             J := 0;                          J := 0;
  2175.             loop                             loop
  2176.                J := J + 1;                      J := J + 1;
  2177.                if A(I, J) = 0 then
  2178.                   exit;                         exit when A(I, J) = 0;
  2179.                end if;
  2180.             end loop;                        end loop;
  2181.             B(I) := J;                       B(I) := J;
  2182.          end loop;                        end loop;
  2183.  
  2184. The statement exit; exits the innermost loop.  In the example at the left,
  2185. exit; transfers control to the statement B(I) := J;.  Since exit; is often the
  2186. only statement in an if block, exit when is available to abbreviate an if block
  2187. with exit; as its only statement.  The two examples above are equivalent.
  2188.  
  2189. Although exit; can appear anywhere inside any kind of loop, well-structured
  2190. Ada programs use only exit when, and then only as the last statement of an
  2191. otherwise infinite loop, as above.  This simulates a "repeat ... until" loop,
  2192. which isn't directly available in Ada.
  2193. 1HPlease type a space to go on, or B to go back.                                           3113 250B248$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       OUTER:
  2194.                        for I in 1 .. 10 loop
  2195.                           J := 0;
  2196.                           loop
  2197.                              J := J + 1;
  2198.                              exit OUTER when A(I, J) = 0;
  2199.                           end loop;
  2200.                           B(I) := J;
  2201.                        end loop OUTER;
  2202.                        K := J;
  2203.  
  2204. An exit statement can exit other than the innermost loop by naming the loop to
  2205. be exited.  In this example, the for loop is named OUTER.  A loop name is any
  2206. Ada identifier, and is followed by a colon.  Of course, OUTER: could have been
  2207. placed on the same line as the for statement.  When a loop is named, the end
  2208. loop statement must repeat the name of the loop.  The exit statement can then
  2209. name the loop to be exited, as in exit OUTER; or exit OUTER when A(I, J) = 0;.
  2210. In this example, the exit statement transfers control to the statement K := J;,
  2211. not to B(I) := J;.
  2212.  
  2213. Well-structured programs don't use exit to leave any loop except the innermost
  2214. loop.  The above example isn't well-structured.
  2215. 1HPlease type a space to go on, or B to go back.                                                               2750 251B249$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                LABELS AND GOTOS
  2216.  
  2217.                        OUTER:
  2218.                        for I in 1 .. 10 loop
  2219.                           J := 0;
  2220.                           loop
  2221.                              J := J + 1;
  2222.                              exit OUTER when A(I, J) = 0;
  2223.                           end loop;
  2224.                           B(I) := J;
  2225.                        end loop OUTER;
  2226.                        K := J;
  2227.  
  2228. Although an Ada loop name looks exactly like a Pascal label, OUTER: is not a
  2229. label, and the program can't goto OUTER.  An Ada label looks like this:
  2230.  
  2231.                                    << JAIL >>
  2232.  
  2233. The << ... >> makes the label very conspicuous, whether it's on the same line
  2234. as a statement or on a line by itself.  The program can then say goto JAIL;.
  2235. Like all reserved words, goto can't contain a space.  Well-structured Ada
  2236. programs don't need gotos and labels, so their use is very rare.
  2237. 1HPlease type a space to go on, or B to go back.                          2226125222533254B250$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        I_LOOP:   for I in 1 .. 10 loop
  2238.                                      J := 0;
  2239.                         J_LOOP:      loop
  2240.                                         J := J + 1;
  2241.                                         exit;
  2242.                                      end loop J_LOOP;
  2243.                                      L := J;
  2244.                                   end loop I_LOOP;
  2245.                                   M := J;
  2246.  
  2247.  
  2248. In the program segment above, which statement will be executed after exit;?
  2249.  
  2250.                            1.  L := J;
  2251.  
  2252.                            2.  M := J;
  2253.  
  2254.                            3.  for I in 1 .. 10 loop
  2255. 1HPlease press 1, 2, or 3, or B to go back.                                                  2139 255B251Q251$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        I_LOOP:   for I in 1 .. 10 loop
  2256.                                      J := 0;
  2257.                         J_LOOP:      loop
  2258.                                         J := J + 1;
  2259.                                         exit;
  2260.                                      end loop J_LOOP;
  2261.                                      L := J;
  2262.                                   end loop I_LOOP;
  2263.                                   M := J;
  2264.  
  2265.  
  2266. You're right!  When used without a name, exit; leaves the innermost loop, so
  2267. the next statement executed is L := J;.
  2268. 1HPlease type a space to go on, or B or Q to go back to the question.                                     2034 255B251Q251$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        I_LOOP:   for I in 1 .. 10 loop
  2269.                                      J := 0;
  2270.                         J_LOOP:      loop
  2271.                                         J := J + 1;
  2272.                                         exit;
  2273.                                      end loop J_LOOP;
  2274.                                      L := J;
  2275.                                   end loop I_LOOP;
  2276.                                   M := J;
  2277.  
  2278.  
  2279. No, when used without a name, exit; leaves the innermost loop.
  2280. 1HPlease type a space to go on, or B or Q to go back to the question.                                          2159 255B251Q251$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        I_LOOP:   for I in 1 .. 10 loop
  2281.                                      J := 0;
  2282.                         J_LOOP:      loop
  2283.                                         J := J + 1;
  2284.                                         exit;
  2285.                                      end loop J_LOOP;
  2286.                                      L := J;
  2287.                                   end loop I_LOOP;
  2288.                                   M := J;
  2289.  
  2290.  
  2291. No, when used without a name, exit; leaves the innermost loop.  The next
  2292. statement executed will be the first statement after the end of the innermost
  2293. loop.
  2294. 1HPlease type a space to go on, or B or Q to go back to the question.                 3713 256B251$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              THE "CASE" CONSTRUCT
  2295.  
  2296. case C is                        In this example, assume that C is of type
  2297.    when '*' =>                   CHARACTER.  The expression being tested (C),
  2298.       -----;                     must have a discrete type: integer or
  2299.       -----;                     enumeration type.  The case construct must
  2300.    when '#' | '$' =>             handle all possible values, but when others is
  2301.       -----;                     available.  If no action is desired for
  2302.       -----;                     characters not mentioned, we can write when
  2303.       -----;                     others => null;.  The Ada statement null; does
  2304.    when '0' .. '9' =>            nothing.  Note that the vertical bar can be
  2305.       -----;                     used to apply several cases to one block of
  2306.    when 'A'..'Z' | 'a'..'z' =>   code, and that ranges can be used.  Here, if C
  2307.       -----;                     is '*', the first block is executed; if it's
  2308.       -----;                     '#' or '$', the second block is executed.  If
  2309.       -----;                     it's a digit, the third block is executed, and
  2310.    when others =>                if it's a letter (upper or lower case), the
  2311.       -----;                     fourth block is executed.  If C is anything
  2312.       -----;                     else, the fifth (last) block of code is
  2313. end case;                        executed.
  2314. 1HPlease type a space to go on, or B to go back.                                                               2758 257B255$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$case C is
  2315.    when '*' =>                        if C = '*' then
  2316.       -----;                             -----;
  2317.       -----;                             -----;
  2318.    when '#' | '$' =>                  elsif C = '#' or C = '$' then
  2319.       -----;                             -----;
  2320.       -----;                             -----;
  2321.       -----;                             -----;
  2322.    when '0' .. '9' =>                 elsif C in '0' .. '9' then
  2323.       -----;                             -----;
  2324.    when 'A'..'Z' | 'a'..'z' =>        elsif C in 'A'..'Z' or C in 'a'..'z' then
  2325.       -----;                             -----;
  2326.       -----;                             -----;
  2327.       -----;                             -----;
  2328.    when others =>                     else
  2329.       -----;                             -----;
  2330.       -----;                             -----;
  2331. end case;                             end if;
  2332.  
  2333. Note that these two examples are equivalent.  In both cases only one block of
  2334. code will be executed.
  2335. 1HPlease type a space to go on, or B to go back.                  2469325812592260B256$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If we have
  2336.  
  2337.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2338.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2339.    F : FLOAT range 0.0 .. 2.0;
  2340.    R : RAINBOW_COLOR;
  2341.    T : TRAFFIC_LIGHT_COLOR;
  2342.  
  2343. then which one of the following program segments is legal?
  2344.  
  2345.             1:                            2:                         3:
  2346.  
  2347.  case R is                       case F is                    case T is
  2348.    when RED | GREEN =>              when 0.0 .. 1.0 =>           when RED =>
  2349.       -----;                           -----;                       -----;
  2350.    when BLUE .. VIOLET =>           when others =>               when others =>
  2351.       -----;                           -----;                       -----;
  2352.  end case;                       end case;                    end case;
  2353.  
  2354. 1HPlease press 1, 2, or 3, or B to go back.       2741 261B257Q257$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2355.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2356.    F : FLOAT range 0.0 .. 2.0;
  2357.    R : RAINBOW_COLOR;
  2358.    T : TRAFFIC_LIGHT_COLOR;
  2359.  
  2360.             1:                            2:                         3:
  2361.  
  2362.  case R is                       case F is                    case T is
  2363.    when RED | GREEN =>              when 0.0 .. 1.0 =>           when RED =>
  2364.       -----;                           -----;                       -----;
  2365.    when BLUE .. VIOLET =>           when others =>               when others =>
  2366.       -----;                           -----;                       -----;
  2367.  end case;                       end case;                    end case;
  2368.  
  2369. You're right!  Number 1 is illegal because it doesn't account for all possible
  2370. values of R, and number 2 is illegal because F doesn't have a discrete type.
  2371. 1HPlease type a space to go on, or B or Q to go back to the question.                                   2535 261B257Q257$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2372.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2373.    F : FLOAT range 0.0 .. 2.0;
  2374.    R : RAINBOW_COLOR;
  2375.    T : TRAFFIC_LIGHT_COLOR;
  2376.  
  2377.             1:                            2:                         3:
  2378.  
  2379.  case R is                       case F is                    case T is
  2380.    when RED | GREEN =>              when 0.0 .. 1.0 =>           when RED =>
  2381.       -----;                           -----;                       -----;
  2382.    when BLUE .. VIOLET =>           when others =>               when others =>
  2383.       -----;                           -----;                       -----;
  2384.  end case;                       end case;                    end case;
  2385.  
  2386. No, number 1 is illegal because it doesn't account for all the possible values
  2387. of R.
  2388. 1HPlease type a space to go on, or B or Q to go back to the question.                                         2513 261B257Q257$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2389.    type TRAFFIC_LIGHT_COLOR is (RED, AMBER, GREEN);
  2390.    F : FLOAT range 0.0 .. 2.0;
  2391.    R : RAINBOW_COLOR;
  2392.    T : TRAFFIC_LIGHT_COLOR;
  2393.  
  2394.             1:                            2:                         3:
  2395.  
  2396.  case R is                       case F is                    case T is
  2397.    when RED | GREEN =>              when 0.0 .. 1.0 =>           when RED =>
  2398.       -----;                           -----;                       -----;
  2399.    when BLUE .. VIOLET =>           when others =>               when others =>
  2400.       -----;                           -----;                       -----;
  2401.  end case;                       end case;                    end case;
  2402.  
  2403. No, number 2 is illegal because F doesn't have a discrete type.
  2404. 1HPlease type a space to go on, or B or Q to go back to the question.                                                               2856 262B257$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          BRIEF OVERVIEW OF FUNCTIONS
  2405.  
  2406.               procedure FUNCT_DEMO is
  2407.                  X : FLOAT := 1.2;
  2408.                  Y : FLOAT;
  2409.                  function TWICE(DUMMY : in FLOAT) return FLOAT is
  2410.                     ANSWER : FLOAT;
  2411.                  begin
  2412.                     ANSWER := DUMMY * 2.0;
  2413.                     return ANSWER;
  2414.                  end TWICE;
  2415.               begin
  2416.                  Y := TWICE(X);
  2417.               end FUNCT_DEMO;
  2418.  
  2419. Later we'll cover functions and procedures in detail, but let's look briefly at
  2420. functions now so we can do Outside Assignment 2.  Here procedure FUNCT_DEMO
  2421. locally declares a function TWICE.  TWICE can be called only from within
  2422. FUNCT_DEMO:  Y := TWICE(X);.  Note that the function specification gives the
  2423. name (DUMMY), mode (in) and type (FLOAT) of any dummy arguments, or parameters.
  2424. For functions, the mode of all parameters must be in, never out or in out.  The
  2425. function specification also gives the type being returned, in this case FLOAT.
  2426. 1HPlease type a space to go on, or B to go back.                    2628 263B261$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              procedure FUNCT_DEMO is
  2427.                  X : FLOAT := 1.2;
  2428.                  Y : FLOAT;
  2429.                  function TWICE(DUMMY : in FLOAT) return FLOAT is
  2430.                     ANSWER : FLOAT;
  2431.                  begin
  2432.                     ANSWER := DUMMY * 2.0;
  2433.                     return ANSWER;
  2434.                  end TWICE;
  2435.               begin
  2436.                  Y := TWICE(X);
  2437.               end FUNCT_DEMO;
  2438.  
  2439. The function body must have return followed by an expression of the right type.
  2440. In well-structured functions, this is the last statement before end.  We don't
  2441. return a value by placing the name of the function in an assignment statement,
  2442. as in Fortran.  Note that function TWICE could be written more simply as
  2443.  
  2444.                 function TWICE(DUMMY : in FLOAT) return FLOAT is
  2445.                 begin
  2446.                    return DUMMY * 2.0;
  2447.                 end TWICE;
  2448. 1HPlease type a space to go on, or B to go back.                                                2819 264B262$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         procedure FUNCT_DEMO is
  2449.             X : FLOAT := 1.2;
  2450.             Y : FLOAT;
  2451.             function TWICE(DUMMY : in FLOAT) return FLOAT is separate;
  2452.          begin
  2453.             Y := TWICE(X);
  2454.          end FUNCT_DEMO;
  2455.  
  2456.          separate (FUNCT_DEMO)
  2457.          function TWICE(DUMMY : in FLOAT) return FLOAT is
  2458.          begin
  2459.             return DUMMY * 2.0;
  2460.          end TWICE;
  2461.  
  2462. The function can be placed in a separate file and compiled later.  Here the
  2463. calling program can be compiled once, and later the function can be edited and
  2464. recompiled as often as desired.  TWICE is still local to FUNCT_DEMO.  The
  2465. phrase separate (FUNCT_DEMO) tells Ada that this subprogram is part of the
  2466. previously compiled unit FUNCT_DEMO.  It's as if the function were cut out and
  2467. "pasted" where the calling program says function TWICE ... is separate;.  Ada
  2468. can still compile the call Y := TWICE(X); because the calling program contains
  2469. the specification of the function.
  2470. 1HPlease type a space to go on, or B to go back.                                                         3271 265B263$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              OUTSIDE ASSIGNMENT 2 - EXERCISE IN ENUMERATION TYPES
  2471.  
  2472. Separate compilation is the basis of our next Outside Assignment.  The function
  2473. we want you to write is completely specified by these two lines of Ada:
  2474.  
  2475.       type TRIANGLE is (EQUILATERAL, ISOSCELES, SCALENE, NOT_A_TRIANGLE);
  2476.       function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE;
  2477.  
  2478. From these two lines, it's obvious that the function must decide whether three
  2479. integers, representing the lengths of the sides of a triangle, in fact
  2480. represent an equilateral triangle, an isosceles triangle, a scalene triangle,
  2481. or no triangle at all.  (An equilateral triangle has three equal sides; an
  2482. isosceles triangle has only two equal sides.  A scalene triangle has sides of
  2483. three different lengths, and the integers -1, 0, 5 represent no triangle.)
  2484.  
  2485. A test driver for your function is already written, and is in the file
  2486. TRITEST.ADA.  A listing starts on page 9 of your printed course notes.  You
  2487. need not understand the test driver.  It's sufficient to know that if your
  2488. function passes all the tests, the message "Congratulations, you completed the
  2489. assignment!" is shown.  For any failed tests, the test driver displays the test
  2490. case, the answer from your function, and the correct answer.  This will help
  2491. you in debugging your function.
  2492. 1HPlease type a space to go on, or B to go back.     2765 266B264$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that the test driver, which is the main program, contains
  2493.  
  2494.   type TRIANGLE is (EQUILATERAL, ISOSCELES, SCALENE, NOT_A_TRIANGLE);
  2495.   function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is separate;
  2496.  
  2497. This allows you to edit and recompile your function as often as you like,
  2498. without having to recompile the test driver.  Since type TRIANGLE is defined in
  2499. the calling program, you should not define it in your function.
  2500.  
  2501. To get you started, a dummy solution is given in TRITYPE.DUM.  You can copy it
  2502. and edit the copy to become your real solution.  It looks like this:
  2503.  
  2504.        -- Dummy solution for Outside Assignment 2
  2505.        -- Edit to become your real solution.
  2506.        separate (TRITEST)
  2507.        function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is
  2508.        begin
  2509.           return NOT_A_TRIANGLE;
  2510.        end TRITYPE;
  2511.  
  2512. If you wish, you can compile this dummy solution before editing it.  Then
  2513. you'll see what error messages from the test driver look like.
  2514. 1HPlease type a space to go on, or B to go back.           2570 267B265$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       -- Dummy solution for Outside Assignment 2
  2515.        -- Edit to become your real solution.
  2516.        separate (TRITEST)
  2517.        function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is
  2518.        begin
  2519.           return NOT_A_TRIANGLE;
  2520.        end TRITYPE;
  2521.  
  2522. When you do edit the function, you'll probably want to remove or change the
  2523. first two comment lines.  Don't change the lines highlighted above.  You may
  2524. want to create a new variable of type TRIANGLE, and return that variable
  2525. instead of the constant NOT_A_TRIANGLE at the end of your function:
  2526.  
  2527.        separate (TRITEST)
  2528.        function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is
  2529.           ANSWER : TRIANGLE;
  2530.        begin
  2531.           if ... end if;
  2532.           return ANSWER;
  2533.        end TRITYPE;
  2534.  
  2535. However, that's not the only way to solve the problem, just a suggestion.
  2536. 1HPlease type a space to go on, or B to go back.      2453 268B266$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Here are the steps to follow for Outside Assignment 2.  They're also in your
  2537. printed course notes on page 11:
  2538.  
  2539. 1.  Compile the test driver TRITEST.ADA.  Also, make a copy of the dummy
  2540.     solution by typing COPY TRITYPE.DUM TRITYPE.ADA.  You need do this step
  2541.     only once.
  2542.  
  2543. 2.  Edit TRITYPE.ADA to become your real solution.  You can skip this step the
  2544.     first time through, to see error messages from the test driver.
  2545.  
  2546. 3.  Compile your solution TRITYPE.ADA.  If there are compiler errors, go back
  2547.     to step 2.
  2548.  
  2549. 4.  Link with the name of the main program TRITEST.  Then execute.  If the test
  2550.     driver prints error messages, go back to step 2.
  2551.  
  2552. 5.  When the message "Congratulations, you completed the assignment!" is
  2553.     printed, you'll have a chance to compare your solution with ours.
  2554. 1HPlease type a space to go on, or B to go back.                       2160 269B267$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Remember that a function can't change the values of its parameters (in this
  2555. case, LEN1, LEN2, and LEN3), because function parameters are always of mode in.
  2556.  
  2557. This assignment should be a simple exercise in enumeration types and the
  2558. control constructs.  Our solution easily fits on one screen.  If you find your
  2559. solution getting long and difficult, you should probably think through the
  2560. problem again.  See if there's a simple way to test for the four possible
  2561. answers.
  2562.  
  2563. Please type X to exit ADA-TUTR temporarily, and try Outside Assignment 2.  Work
  2564. at your own pace; there's no deadline.  Good luck!
  2565. 1HPlease type X to exit, a space to go on, or B to go back.                2222 270B268$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 2!
  2566.  
  2567. Our solution is in TRITYPE.ANS.  It looks like this:
  2568.  
  2569. -- Our solution to Outside Assignment 2:
  2570. separate (TRITEST)
  2571. function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE is
  2572.    ANSWER : TRIANGLE;
  2573. begin
  2574.    if LEN1 + LEN2 <= LEN3  or LEN1 + LEN3 <= LEN2  or LEN2 + LEN3 <= LEN1  then
  2575.       ANSWER := NOT_A_TRIANGLE;
  2576.    elsif  LEN1 = LEN2  and  LEN2 = LEN3  then
  2577.       ANSWER := EQUILATERAL;
  2578.    elsif  LEN1 = LEN2  or  LEN2 = LEN3  or  LEN1 = LEN3  then
  2579.       ANSWER := ISOSCELES;
  2580.    else
  2581.       ANSWER := SCALENE;
  2582.    end if;
  2583.    return ANSWER;
  2584. end TRITYPE;
  2585. 1HPlease type a space to go on, or B to go back.                                                      2670 271B269$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that it isn't necessary to include tests for sides <= 0, because if any
  2586. side <= 0, one of the three tests in the following would have to catch that:
  2587.  
  2588. if  LEN1 + LEN2 <= LEN3  or  LEN1 + LEN3 <= LEN2  or  LEN2 + LEN3 <= LEN1  then
  2589.    ANSWER := NOT_A_TRIANGLE;
  2590.  
  2591. However, most students include tests for sides <= 0, so if you did, don't feel
  2592. bad.  It doesn't do any harm.
  2593.  
  2594. You must have realized by now that it's impossible to draw a triangle with
  2595. sides 1, 2, and 3.  The sum of any two sides must be greater than the third.
  2596.  
  2597. There are many correct ways to solve this problem.  Some students sort the
  2598. three sides first.  Some initialize ANSWER to SCALENE in the declarative region
  2599. and omit the code
  2600.  
  2601.                              else
  2602.                                 ANSWER := SCALENE;
  2603.  
  2604. If you saw the message "Congratulations, you completed the assignment!" you can
  2605. consider your solution correct.  Let's go on to discuss Records and Arrays.
  2606. 1HPlease type a space to go on, or B to go back.      2869 272B270$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    RECORDS
  2607.  
  2608. record lets us group several declarations together and refer to them as one:
  2609.  
  2610.      type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  2611.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2612.      type DATE is
  2613.         record
  2614.            DAY   : DAY_SUBTYPE;   -- Note that DAY_SUBTYPE and
  2615.            MONTH : MONTH_TYPE;    -- MONTH_TYPE must be defined
  2616.            YEAR  : INTEGER;       -- before type DATE is defined.
  2617.         end record;
  2618.      USA : DATE;
  2619.  
  2620. In this example, USA has three parts (called "fields"):  USA.DAYUSA.MONTH,
  2621. and USA.YEAR.  The fields of a record can be of any type, including other
  2622. records.  Here USA.DAY is of type INTEGER, USA.MONTH is of type MONTH_TYPE, and
  2623. USA.YEAR is of type INTEGER.  The parts of USA may be used separately:
  2624.  
  2625.                                USA.DAY := 4;
  2626.                                USA.MONTH := JUL;
  2627.                                USA.YEAR := 1776;
  2628. 1HPlease type a space to go on, or B to go back.       3018 273B271$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  2629.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2630.      type DATE is
  2631.         record
  2632.            DAY   : DAY_SUBTYPE;
  2633.            MONTH : MONTH_TYPE;
  2634.            YEAR  : INTEGER;
  2635.         end record;
  2636.      USA : DATE;
  2637.  
  2638. However, USA can also be used as one object.  For example, we could have
  2639. assigned all three fields in one statement:  USA := (4, JUL, 1776);.  Here the
  2640. object on the left is of type DATE, and the object on the right is called an
  2641. aggregate.  The aggregate fits the type DATE because it contains an INTEGER, a
  2642. MONTH_TYPE, and another INTEGER.  This aggregate is said to use positional
  2643. notation because its three parts appear in the same order as the three parts of
  2644. the record definition:  first DAY, then MONTH, then YEAR.
  2645.  
  2646. We can specify the parts of an aggregate in any order we like if we use named
  2647. notation: USA := (MONTH => JUL, DAY => 4, YEAR => 1776);.  The symbol => is
  2648. read "arrow."  Using named notation often improves program readability,
  2649. especially if the names of the fields are well chosen.
  2650. 1HPlease type a space to go on, or B to go back.                                                          2363 274B272$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  2651.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2652.      type DATE is
  2653.         record
  2654.            DAY   : DAY_SUBTYPE;
  2655.            MONTH : MONTH_TYPE;
  2656.            YEAR  : INTEGER;
  2657.         end record;
  2658.      USA : DATE;
  2659.  
  2660. We can switch from positional to named notation in an aggregate.  But once we
  2661. use named notation, the compiler loses track of position, so we can't switch
  2662. back to positional.  For example, the following is legal:
  2663.  
  2664.                     USA := (4, YEAR => 1776, MONTH => JUL);
  2665.  
  2666. But the following is illegal because positional notation can't follow named in
  2667. an aggregate:
  2668.  
  2669.                    USA := (4, YEAR => 1776, JUL); -- illegal
  2670. 1HPlease type a space to go on, or B to go back.             21743275127622774278B273$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    procedure RECORD_EXERCISE is
  2671.        type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  2672.        subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2673.        type DATE is
  2674.           record
  2675.              DAY   : DAY_SUBTYPE;
  2676.              MONTH : MONTH_TYPE;
  2677.              YEAR  : INTEGER;
  2678.           end record;
  2679.        D1, D2, D3 : DATE;  -- 1
  2680.     begin
  2681.        D1 := (MONTH => AUG, DAY => 14, YEAR => 1945);  -- 2
  2682.        D2.DAY := 22;
  2683.        D2.MONTH := 1;  -- 3
  2684.        D2.YEAR := 1983;
  2685.        D3 := D2;  -- 4
  2686.     end RECORD_EXERCISE;
  2687.  
  2688. Which commented line in the above program is illegal?
  2689. 1HPlease press 1, 2, 3, or 4, or B to go back.  1515 279B274Q274$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       D2.MONTH := 1;  -- 3
  2690.  
  2691. You're right!  This statement is illegal, because the types are mixed.
  2692. D2.MONTH is of type MONTH_TYPE, and 1 is an integer.
  2693. 1HPlease type a space to go on, or B or Q to go back to the question.                                                             1458 279B274Q274$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       D1, D2, D3 : DATE;  -- 1
  2694.  
  2695. No, this statement is legal, because several objects may be declared in one
  2696. statement, if the objects are separated by commas.
  2697. 1HPlease type a space to go on, or B or Q to go back to the question.                  1517 279B274Q274$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       D1 := (MONTH => AUG, DAY => 14, YEAR => 1945);  -- 2
  2698.  
  2699. No, this statement is legal, because the fields within the aggregate may appear
  2700. in any order when named notation is used.
  2701. 1HPlease type a space to go on, or B or Q to go back to the question.                                                           1474 279B274Q274$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       D3 := D2;  -- 4
  2702.  
  2703. No, this statement is legal, because D3 and D2 both have the same type: DATE.
  2704. An entire record can be assigned with one statement.
  2705. 1HPlease type a space to go on, or B or Q to go back to the question.  3247 280B274$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                     ARRAYS
  2706.  
  2707. To declare an array in Ada, we specify the type and range of the subscript,
  2708. followed by the type of the elements of the array.  The subscript can have any
  2709. discrete type (integer or enumeration), and the elements of the array can be of
  2710. any type at all, including records and other arrays.  There are three ways to
  2711. declare an array in Ada.  Here are three examples of the most direct, but least
  2712. flexible, way (types RAINBOW_COLOR and DATE must be defined earlier):
  2713.  
  2714. A : array(RAINBOW_COLOR range ORANGE .. BLUE) of DATE;
  2715.    -- A four-element array, each element of which is a record with three parts.
  2716.    -- The allowable subscripts are ORANGE, YELLOW, GREEN, and BLUE.  Note that
  2717.    -- A(YELLOW) is of type DATE, and A(YELLOW).YEAR is of type INTEGER.
  2718. B : array(INTEGER range -10 .. 10) of INTEGER;
  2719.    -- An array of 21 INTEGERs, with INTEGER subscripts.
  2720. C : array(0 .. 30) of FLOAT;
  2721.    -- Here (0 .. 30) is understood to mean (INTEGER range 0 .. 30), and we have
  2722.    -- an array of 31 FLOATs, with INTEGER subscripts.
  2723.  
  2724. A subscript can be an expression; if I is an INTEGER, we can write C(2*I).  If
  2725. a subscript is out-of-range (for example, A(RED) or C(-32)), the program will
  2726. raise a CONSTRAINT_ERROR.
  2727. 1HPlease type a space to go on, or B to go back.                             2969 281B279$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$This direct method of declaring arrays is usually used to create single arrays
  2728. for table lookup, etc., where there's no need to have several arrays of the
  2729. same type.  A better way to declare an array is to specify a type name for the
  2730. array itself.  Then several objects can be declared to have that same type.
  2731. For example,
  2732.  
  2733.                   type VECTOR100 is array(1 .. 100) of FLOAT;
  2734.                   type VECTOR300 is array(1 .. 300) of FLOAT;
  2735.                   D, E, F : VECTOR100;
  2736.                   G, H    : VECTOR300;
  2737.  
  2738. Here D, E, and F are all of type VECTOR100, so we can write D := E;  and assign
  2739. the entire array with one statement.  Similarly, we can write G := H;, but not
  2740. G := F;.
  2741.  
  2742. Note that the example above takes four statements.  An even better way to
  2743. declare arrays is to leave the range of the subscript unspecified with the box
  2744. symbol, <>, specifying the range when declaring the objects.  For example,
  2745.  
  2746.                 type VECTOR is array(INTEGER range <>) of FLOAT;
  2747.                 D, E, F : VECTOR(1 .. 100);
  2748.                 G, H    : VECTOR(1 .. 300);
  2749. 1HPlease type a space to go on, or B to go back.       3023 282B280$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$There are two errors to avoid when declaring arrays in this way.  One is to
  2750. declare a type with the box symbol for the range of the subscript, and then
  2751. fail to specify the range when declaring an object (other than a constant):
  2752.  
  2753.                type VECTOR is array(INTEGER range <>) of FLOAT;
  2754.                D1 : VECTOR; -- Illegal
  2755.                D2 : constant VECTOR := (2.3, 4.5, 4.0); -- Legal
  2756.  
  2757. This error is called unconstrained array.  Unconstrained arrays are legal in
  2758. dummy arguments ("formal parameters") of procedures and functions, and a
  2759. function can return an unconstrained array type.  (We'll learn about these
  2760. things later.)  But an unconstrained array is illegal when declaring a
  2761. variable, because the compiler needs to know the range of the subscript.
  2762.  
  2763. The other error is to specify the range of the subscript twice: once when
  2764. declaring the type and once when declaring the object:
  2765.  
  2766.                   type VECTOR100 is array(1 .. 100) of FLOAT;
  2767.                   D2 : VECTOR100(1 .. 100);  -- Illegal
  2768.  
  2769. Even if the two ranges agree, this is illegal and is called doubly constrained
  2770. array.
  2771. 1HPlease type a space to go on, or B to go back.                                                     2552 283B281$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In an array declaration, we can totally omit the range of the subscript (not
  2772. even supplying a box), if the type or subtype of the subscript has a reasonable
  2773. number of possible values.  For example, in
  2774.  
  2775.    type RAINBOW_COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET);
  2776.    R : array(RAINBOW_COLOR) of FLOAT;
  2777.  
  2778. we have an array of seven FLOATs, because there are seven possible values of
  2779. type RAINBOW_COLOR.  Similarly,
  2780.  
  2781.                         V : array(CHARACTER) of BOOLEAN;
  2782.  
  2783. creates an array of 128 BOOLEANs.  However, J : array(INTEGER) of FLOAT; is an
  2784. attempt to declare a very large array indeed!  In a case like this, we can use
  2785. a subtype in the subscript declaration:
  2786.  
  2787.                  subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2788.                  J : array(DAY_SUBTYPE) of FLOAT;
  2789.  
  2790. This creates an array of 31 FLOATs.
  2791. 1HPlease type a space to go on, or B to go back.                        3169 284B282$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The attributes FIRST and LAST, which we've seen with discrete types, can also
  2792. be used with array types and with the array names themselves.  For example,
  2793.  
  2794.                  type MY_VECTOR is array(30 .. 33) of INTEGER;
  2795.                  MV : MY_VECTOR;
  2796.                  ...
  2797.                  MV(30) := 1000;
  2798.                  MV(31) := 20;
  2799.                  MV(32) := -70;
  2800.                  MV(33) := -500;
  2801.  
  2802. Here MV'FIRST and MY_VECTOR'FIRST are both 30.  MV'LAST and MY_VECTOR'LAST are
  2803. both 33.  Note that FIRST and LAST refer to the subscripts, not to the values
  2804. of the array elements.  Thus MV'FIRST is not 1000.  To obtain the value of the
  2805. first element, we would use MV'FIRST as a subscript.  MV(MV'FIRST) is 1000.
  2806.  
  2807. The attribute RANGE is an abbreviation for FIRST .. LAST.  It can be used only
  2808. with array types and array names, not with discrete types.  Thus MV'RANGE and
  2809. MY_VECTOR'RANGE both mean 30 .. 33.  We can't write INTEGER'RANGE, even though
  2810. we can write INTEGER'FIRST and INTEGER'LAST.  The attribute LENGTH is also
  2811. available:  MV'LENGTH and MY_VECTOR'LENGTH are both 4.
  2812. 1HPlease type a space to go on, or B to go back.       2111328512862287B283$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Which one of these is illegal?
  2813.  
  2814.  
  2815.           1.    subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2816.                 type GROUP is array(DAY_SUBTYPE) of FLOAT;
  2817.                 GR : GROUP;
  2818.                 ...
  2819.                 GR(3) := 0.0;
  2820.  
  2821.  
  2822.           2.    type LINE is array(1 .. 10) of INTEGER;
  2823.                 type PAGE is array(1 .. 20) of LINE;
  2824.                 PG : PAGE;
  2825.                 ...
  2826.                 PG(5)(10) := 0;
  2827.  
  2828.  
  2829.           3.    type ROW is array (INTEGER range <>) of INTEGER;
  2830.                 R1 : ROW;
  2831.                 ...
  2832.                 R1(1) := 0;
  2833. 1HPlease press 1, 2, or 3, or B to go back.                                                                 1873 288B284Q284$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          3.    type ROW is array (INTEGER range <>) of INTEGER;
  2834.                 R1 : ROW;
  2835.                 ...
  2836.                 R1(1) := 0;
  2837.  
  2838. You're right!  The above is illegal because the range of the subscript must be
  2839. specified, either in the first line, (INTEGER range 1 .. 10), or in the
  2840. second, R1 : ROW(1 .. 10);, but not both.  This is the unconstrained array
  2841. error mentioned earlier.
  2842. 1HPlease type a space to go on, or B or Q to go back to the question.   1835 288B284Q284$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          1.    subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  2843.                 type GROUP is array(DAY_SUBTYPE) of FLOAT;
  2844.                 GP : GROUP;
  2845.                 ...
  2846.                 GP(3) := 0.0;
  2847.  
  2848. No, the above is legal.  GP is an array of 31 elements.  The subscript ranges
  2849. from 1 to 31, and each element has type FLOAT.  Therefore, GP(3) has type
  2850. FLOAT, and the assignment is legal.
  2851. 1HPlease type a space to go on, or B or Q to go back to the question.                                         2113 288B284Q284$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          2.    type LINE is array(1 .. 10) of INTEGER;
  2852.                 type PAGE is array(1 .. 20) of LINE;
  2853.                 PG : PAGE;
  2854.                 ...
  2855.                 PG(5)(10) := 0;
  2856.  
  2857. No, the above is legal.  The elements of an array can be of any type, including
  2858. other arrays.  Here PG has type PAGE, which is an array of LINE.  Therefore
  2859. PG(5) has type LINE (which is an array of INTEGER), and PG(5)(10) has type
  2860. INTEGER.  Thus the assignment is legal.  The notation PG(5)(10) may seem
  2861. strange, but it's correct Ada when we have an array of arrays.
  2862. 1HPlease type a space to go on, or B or Q to go back to the question.                                                               2943 289B284$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            MULTIDIMENSIONAL ARRAYS
  2863.  
  2864. Ada arrays may have any number of dimensions, and the subscripts may be of
  2865. different discrete types.  For example, assuming RAINBOW_COLOR, MONTH_TYPE, and
  2866. DATE have already been defined, we can write
  2867.  
  2868.      X : array(INTEGER range -10 .. -1, RAINBOW_COLOR range ORANGE .. BLUE,
  2869.                MONTH_TYPE range FEB .. JUN) of DATE;
  2870.  
  2871. Here the first subscript is of type INTEGER and has 10 possible values, the
  2872. second subscript is of type RAINBOW_COLOR and has four possible values, and the
  2873. third subscript has type MONTH_TYPE with five possible values.  Thus we have
  2874. a three-dimensional array of 10 * 4 * 5 = 200 DATEs.  One element of the array
  2875. might be X(-5, GREEN, APR); one field of that element might be
  2876. X(-5, GREEN, APR).YEAR.  The array in this example probably has no use, other
  2877. than demonstrating that multiple subscripts need not have the same type.
  2878.  
  2879. If one subscript of a multidimensional array is constrained, they must all be
  2880. constrained.  We can't write
  2881.  
  2882.            X : array(1 .. 5, INTEGER range <>) of FLOAT;  -- illegal
  2883. 1HPlease type a space to go on, or B to go back.                                 3046 290B288$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Arrays may be initialized and assigned with aggregates, and both positional and
  2884. named notation may be used.  For example, arrays A and B are equal here:
  2885.  
  2886.  type VECTOR5 is array(1 .. 5) of FLOAT;
  2887.  A : constant VECTOR5 := (2.0, 4.0, 8.0, 16.0, 32.0);
  2888.  B : constant VECTOR5 := (1 => 2.0, 2 => 4.0, 3 => 8.0, 4 => 16.0, 5 => 32.0);
  2889.  
  2890. The aggregate must fill the whole array, but the reserved word others is
  2891. available.  Here's an array of 500 FLOAT variables, all initialized to 0.0:
  2892.  
  2893.                   type VECTOR500 is array(1 .. 500) of FLOAT;
  2894.                   V1 : VECTOR500 := (others => 0.0);
  2895.  
  2896. If others follows named notation, it's best to qualify the aggregate with the
  2897. type name.  Here W(10) = 1.3, W(15) = -30.7, and the rest of the array is 0.0:
  2898.  
  2899.      W : VECTOR500 := VECTOR500'(10 => 1.3,  15 => -30.7,  others => 0.0);
  2900.  
  2901. Sometimes we must qualify an aggregate when others is used with named notation;
  2902. at other times it's optional.  The rules (LRM section 4.3.2, paragraphs 4-8)
  2903. are very complicated.  It's easiest always to qualify an aggregate when others
  2904. follows named notation, as shown above.
  2905. 1HPlease type a space to go on, or B to go back.                              2243 291B289$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Multidimensional arrays can be initialized or assigned with nested aggregates.
  2906. This example creates a two-dimensional array of FLOATs, initializing all 50
  2907. elements to 1.0:
  2908.  
  2909.       MAT : array(0 .. 9, 1 .. 5) of FLOAT := (others => (others => 1.0));
  2910.  
  2911. Here X is a 10-by-10 array of INTEGERs.  All elements are 0, except X(4, 5),
  2912. which is 1:
  2913.  
  2914.       type SQUARE10 is array (1 .. 10, 1 .. 10) of INTEGER;
  2915.       X : SQUARE10 := SQUARE10'(     4     =>   (5 => 1, others => 0),
  2916.                                    others  =>       (others => 0)       );
  2917.  
  2918. Note that in this second example, we qualified the aggregate because others
  2919. follows named notation.
  2920. 1HPlease type a space to go on, or B to go back.                                 2964 292B290$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In array aggregates, multiple choices can be denoted with the vertical bar (|),
  2921. shift-backslash on your keyboard.  In this array, the elements with odd
  2922. subscripts are TRUE, while the elements with even subscripts are FALSE:
  2923.  
  2924.           type DECADE is array(1 .. 10) of BOOLEAN;
  2925.           D1 : DECADE;
  2926.           ...
  2927.           D1 := DECADE'(1 | 3 | 5 | 7 | 9 => TRUE,  others => FALSE);
  2928.  
  2929. Here we assigned to D1 with an executable statement for variety; we could also
  2930. have initialized D1 in the declarative region with the same aggregate.  Some
  2931. people read the vertical bar as "and," others as "or."  One can say, "Elements
  2932. 1, and 3, and 5, and 7, and 9 are TRUE," or one can say, "If the subscript is
  2933. 1, or 3, or 5, or 7, or 9, the array element is TRUE."
  2934.  
  2935. Array aggregates can also contain ranges.  In this array, elements 1 and 6 - 10
  2936. are 1; the rest are 0.  Arrays L1 and L2 are equal:
  2937.  
  2938.          type LINE15 is array(1 .. 15) of INTEGER;
  2939.          L1 : LINE15 := LINE15'(1 | 6 .. 10 => 1,  others => 0);
  2940.          L2 : LINE15 := (1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0);
  2941. 1HPlease type a space to go on, or B to go back.            2028 293B291$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The "short circuit" forms can prevent us from using array subscripts that are
  2942. out of range.  For example, if we write
  2943.  
  2944.                     A : array(1 .. 10) of FLOAT;
  2945.                     I : INTEGER;
  2946.                     ...
  2947.                     if I in A'RANGE and then A(I) = 0.0 then
  2948.                        -----;
  2949.                        -----;  (block of code)
  2950.                        -----;
  2951.                     end if;
  2952.  
  2953. then we know the program won't try to evaluate A(I) when I is outside the range
  2954. 1 to 10.
  2955. 1HPlease type a space to go on, or B to go back.                                                23491294229532964297B292$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$with TEXT_IO; use TEXT_IO;
  2956. procedure ARRAY_QUIZ is
  2957.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  2958.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  2959.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  2960.    VOWELS : SET_OF_LETTERS :=
  2961.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  2962.    LETTER : CAPITAL_LETTER;
  2963. begin
  2964.    LETTER := 'E';
  2965.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  2966. end ARRAY_QUIZ;
  2967.  
  2968.                         What will this program print?
  2969.  
  2970.                         1.  The program will print 1.
  2971.  
  2972.                         2.  The program will print 2.
  2973.  
  2974.                         3.  The program will print TRUE.
  2975.  
  2976.                         4.  The program will print E.
  2977. 1HPlease press 1, 2, 3, or 4, or B to go back.                           2371 298B293Q293$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$with TEXT_IO; use TEXT_IO;
  2978. procedure ARRAY_QUIZ is
  2979.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  2980.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  2981.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  2982.    VOWELS : SET_OF_LETTERS :=
  2983.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  2984.    LETTER : CAPITAL_LETTER;
  2985. begin
  2986.    LETTER := 'E';
  2987.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  2988. end ARRAY_QUIZ;
  2989.  
  2990.  
  2991. You're right!  VOWELS has 26 elements, with subscripts 'A' through 'Z'.
  2992. VOWELS(LETTER) is VOWELS('E'), which is TRUE, and since Ada defines
  2993.  
  2994.                          type BOOLEAN is (FALSE, TRUE);
  2995.  
  2996. and the positions are numbered starting from 0, BOOLEAN'POS(TRUE) is 1.
  2997. 1HPlease type a space to go on, or B or Q to go back to the question.     2219 298B293Q293$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$with TEXT_IO; use TEXT_IO;
  2998. procedure ARRAY_QUIZ is
  2999.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  3000.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  3001.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  3002.    VOWELS : SET_OF_LETTERS :=
  3003.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  3004.    LETTER : CAPITAL_LETTER;
  3005. begin
  3006.    LETTER := 'E';
  3007.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  3008. end ARRAY_QUIZ;
  3009.  
  3010.  
  3011. No.  Recall that Ada defines
  3012.  
  3013.                          type BOOLEAN is (FALSE, TRUE);
  3014.  
  3015. and that the positions are numbered starting with 0 for the POS attribute.
  3016. 1HPlease type a space to go on, or B or Q to go back to the question.                                                         2270 298B293Q293$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$with TEXT_IO; use TEXT_IO;
  3017. procedure ARRAY_QUIZ is
  3018.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  3019.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  3020.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  3021.    VOWELS : SET_OF_LETTERS :=
  3022.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  3023.    LETTER : CAPITAL_LETTER;
  3024. begin
  3025.    LETTER := 'E';
  3026.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  3027. end ARRAY_QUIZ;
  3028.  
  3029.  
  3030. No.  Indeed VOWELS(LETTER) is VOWELS('E'), which is TRUE, but the program takes
  3031. the BOOLEAN'POS of VOWELS(LETTER).  Recall that the attribute POS converts from
  3032. a discrete type (in this case, BOOLEAN) to an integer.
  3033. 1HPlease type a space to go on, or B or Q to go back to the question.      2343 298B293Q293$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$with TEXT_IO; use TEXT_IO;
  3034. procedure ARRAY_QUIZ is
  3035.    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  3036.    subtype CAPITAL_LETTER is CHARACTER range 'A' .. 'Z';
  3037.    type SET_OF_LETTERS is array(CAPITAL_LETTER) of BOOLEAN;
  3038.    VOWELS : SET_OF_LETTERS :=
  3039.         SET_OF_LETTERS'('A' | 'E' | 'I' | 'O' | 'U' => TRUE,  others => FALSE);
  3040.    LETTER : CAPITAL_LETTER;
  3041. begin
  3042.    LETTER := 'E';
  3043.    PUT(BOOLEAN'POS(VOWELS(LETTER)));
  3044. end ARRAY_QUIZ;
  3045.  
  3046.  
  3047. No.  While LETTER is 'E', and LETTER appears inside the PUT statement, the
  3048. argument of PUT is the BOOLEAN'POS of one element of array VOWELS
  3049. (specifically, the element whose subscript is 'E').  Recall that the POS
  3050. attribute always returns an integer.
  3051. 1HPlease type a space to go on, or B or Q to go back to the question.                                 3164 299B293$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    STRINGS
  3052.  
  3053. There's one very important array type declaration built into the Ada language.
  3054. As with types BOOLEAN and CHARACTER, and subtypes POSITIVE and NATURAL, this
  3055. definition comes with Ada and shouldn't be repeated in our programs:
  3056.  
  3057.              type STRING is array(POSITIVE range <>) of CHARACTER;
  3058.  
  3059. Thus we can declare, for example, S : STRING(1 .. 5);.  We can't simply write
  3060. S : STRING; because we can't declare unconstrained arrays.  (We can declare
  3061. S : constant STRING := "Hello";).  Note that STRING isn't a special type in
  3062. Ada, it's just an array of CHARACTERs.  Everything we learned about arrays
  3063. applies to STRINGs.  For example, we can assign to S using the same syntax that
  3064. we use when assigning to an array of any other type.  If we write
  3065. S : STRING(1 .. 5); we can write:
  3066.  
  3067.                         S := ('H', 'e', 'l', 'l', 'o');
  3068.  
  3069. However, this notation is clumsy, so Ada allows us to abbreviate an array of
  3070. CHARACTER constants using the double quote.  Thus S := "Hello"; is equivalent
  3071. to the statement above.  If a quotation mark appears inside the string, it must
  3072. be doubled.  Thus TEXT_IO.PUT_LINE("a ""big"" man"); will print a "big" man.
  3073. 1HPlease type a space to go on, or B to go back.            3166 300B298$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$It may seem disappointing that Ada STRINGs have fixed length, and that we can't
  3074. declare a variable S : STRING;.  Later we'll learn how to define our own type
  3075. TEXT to get around this restriction and simulate variable-length STRINGs.
  3076.  
  3077. When arrays are assigned, the lengths must be the same on both sides of the :=,
  3078. and the types of the elements must be the same, but the subscripts needn't be
  3079. the same.  For example, if we have
  3080.  
  3081.                 type VECTOR is array(INTEGER range <>) of FLOAT;
  3082.                 V1 : VECTOR(1 .. 5);
  3083.                 V2 : VECTOR(2 .. 6) := (others => 0.0);
  3084.  
  3085.                 S1 : STRING(1 .. 5);
  3086.                 S2 : STRING(2 .. 6) := (others => ' ');
  3087.  
  3088. then we can write V1 := V2; and S1 := S2; even though the subscripts are
  3089. different, because the array lengths are the same and the element types are the
  3090. same.  But we'll get a CONSTRAINT_ERROR if we write S1 := "Hello there"; or
  3091. S1 := "Hi"; or V1 := (1.0, 2.0, 3.0);, because these arrays have wrong lengths.
  3092. Ada won't automatically truncate STRINGs or pad with blanks.  Of course, it
  3093. would be easy to write our own procedure to assign STRINGs of different
  3094. lengths, padding or truncating as necessary.
  3095. 1HPlease type a space to go on, or B to go back.          3757 301B299$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A slice of an array is a portion of an array, and is indicated with a range in
  3096. the subscript.  A slice is itself an array.  Some languages use the term
  3097. "substring" to refer to a slice of a STRING, but in Ada we can take a slice of
  3098. any kind of array, not just an array of CHARACTERs.  So instead of "substring,"
  3099. Ada uses the more general term "slice."  For example, if we have
  3100.  
  3101.        A : array(1 .. 10) of INTEGER := (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
  3102.  
  3103. then A(1 .. 3) is the array (1, 2, 3) and A(6 .. 9) is the array (6, 7, 8, 9).
  3104. Similarly, if we have S : STRING(1 .. 11) := "Hello there"; then S(8 .. 11) is
  3105. "here" and S(4 .. 5) is "lo".  We can also write S(1 .. 10) := S(2 .. 11); and
  3106. A(1 .. 3) := A(4 .. 6); since the lengths are the same on both sides.
  3107.  
  3108. If the value preceding .. is greater than the value following it, we have a
  3109. null range.  A slice with a null range has a length of zero, and is called a
  3110. null slice.  In the case of a null slice, the subscript is not checked for
  3111. CONSTRAINT_ERROR.  Thus, even if N is 0 we could write S(1 .. N); which would
  3112. produce the null string "".  This is legal, even though Ada defines
  3113. "type STRING is array(POSITIVE range <>) of CHARACTER;".  Assigning a null
  3114. slice to a null slice does no harm and generates no error; it does nothing.
  3115. Also, if S is a null array, then S'LENGTH is 0, and S'FIRST and S'LAST don't
  3116. exist.  Using FIRST or LAST with a null array will raise a CONSTRAINT_ERROR.
  3117. 1HPlease type a space to go on, or B to go back.                   2537 302B300$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Beginners sometimes confuse a CHARACTER with a STRING of length 1.  If we
  3118. write
  3119.  
  3120.                               S : STRING(1 .. 10);
  3121.                               I : INTEGER := 5;
  3122.  
  3123. then S(I) is a CHARACTER and S(I .. I) is a STRING of length 1.  Also, 'X' is a
  3124. CHARACTER while "X" is a STRING of length 1.  Thus we could write
  3125.  
  3126.                                S(I) := 'X';
  3127.                                S(I .. I) := "X";
  3128.  
  3129. but we'd be mixing types if we were to write S(I) := "X"; or S(I .. I) := 'X';.
  3130.  
  3131. Fortunately, TEXT_IO has a PUT for type CHARACTER as well as a PUT for type
  3132. STRING.  (It also has a GET for each of these types.)  Thus we can write either
  3133. PUT(S(I .. I)); or PUT(S(I));.  However, PUT_LINE and GET_LINE exist only for
  3134. STRINGs, not for CHARACTERs.
  3135. 1HPlease type a space to go on, or B to go back.                                       18244303130423053306530763087309B301$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3136.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3137.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3138.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3139.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3140.     6.  PROMPT : STRING(1 .. 3) := ">";
  3141.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3142.  
  3143.  
  3144. Which one of the above is legal?
  3145. 1HPlease press 1, 2, 3, 4, 5, 6, or 7, or B to go back.                                                    2817 310B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3146.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3147.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3148.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3149.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3150.     6.  PROMPT : STRING(1 .. 3) := ">";
  3151.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3152.  
  3153.  
  3154. You're right!  Number 4 creates HELLO, a STRING of length 5, and initializes it
  3155. to "Hello", a STRING of the same length.  The subscript of HELLO need not start
  3156. at 1, so long as the length is 5.
  3157.  
  3158. Number 1 attempts to create an unconstrained array.  Number 2 has a zero
  3159. subscript, while Ada defines type STRING for POSITIVE subscripts.  Number 3
  3160. should have '*' instead of "*".  Number 5 tries to set each of the first three
  3161. elements, which are CHARACTERs, to a STRING.  Number 6 tries to store a STRING
  3162. of length 1 into a STRING of length 3, and number 7 should have "Hello"
  3163. instead of 'Hello'.
  3164. 1HPlease type a space to go on, or B or Q to go back to the question.                                                           2416 310B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3165.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3166.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3167.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3168.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3169.     6.  PROMPT : STRING(1 .. 3) := ">";
  3170.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3171.  
  3172.  
  3173. No, number 1 is illegal because it tries to create an unconstrained array.  The
  3174. fact that "Hello there" has a definite length doesn't make the statement legal.
  3175. We must constrain the STRING to a length of 11 by writing, for example,
  3176. HELLO  : STRING(1 .. 11) := "Hello there";.  However, it is legal to write
  3177.  
  3178.                    HELLO : constant STRING := "Hello there";
  3179. 1HPlease type a space to go on, or B or Q to go back to the question.                                                            2053 310B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3180.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3181.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3182.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3183.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3184.     6.  PROMPT : STRING(1 .. 3) := ">";
  3185.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3186.  
  3187.  
  3188. No, number 2 is illegal because of the zero subscript.  Ada defines "type
  3189. STRING is array(POSITIVE range <>) of CHARACTER;".  Therefore, the subscripts
  3190. must be 1 or greater.
  3191. 1HPlease type a space to go on, or B or Q to go back to the question.                       2038 310B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3192.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3193.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3194.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3195.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3196.     6.  PROMPT : STRING(1 .. 3) := ">";
  3197.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3198.  
  3199.  
  3200. No, number 3 is illegal because "*" should be '*'.  As it stands, it tries to
  3201. assign a STRING of length 1 to each of the elements, which are CHARACTERs.
  3202. 1HPlease type a space to go on, or B or Q to go back to the question.                                      2436 310B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3203.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3204.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3205.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3206.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3207.     6.  PROMPT : STRING(1 .. 3) := ">";
  3208.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3209.  
  3210.  
  3211. No, number 5 is illegal because it tries to initialize each of the first three
  3212. elements, which are CHARACTERs, to a STRING of length 3.  We could, however,
  3213. have written simply HELLO : STRING(1 .. 5);, and then written the following in
  3214. the executable region:
  3215.  
  3216.                             HELLO(1 .. 3) := "Hel";
  3217.                             HELLO(4) := 'l';
  3218.                             HELLO(5) := 'o';
  3219. 1HPlease type a space to go on, or B or Q to go back to the question.                                        1932 310B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3220.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3221.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3222.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3223.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3224.     6.  PROMPT : STRING(1 .. 3) := ">";
  3225.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3226.  
  3227.  
  3228. No, number 6 is illegal because it tries to assign a STRING of length 1 to a
  3229. STRING of length 3.
  3230. 1HPlease type a space to go on, or B or Q to go back to the question.                                            2162 310B302Q302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    1.  HELLO  : STRING := "Hello there";
  3231.     2.  DIGIT  : STRING(0 .. 9) := "0123456789";
  3232.     3.  LINE   : STRING(1 .. 80) := (others => "*");
  3233.     4.  HELLO  : STRING(2 .. 6) := "Hello";
  3234.     5.  HELLO  : STRING(1 .. 5) := (1 .. 3 => "Hel",  4 => 'l',  5 => 'o');
  3235.     6.  PROMPT : STRING(1 .. 3) := ">";
  3236.     7.  HELLO  : STRING(1 .. 5) := 'Hello';
  3237.  
  3238.  
  3239. No, number 7 is illegal because it should say "Hello" instead of 'Hello'.  Ada
  3240. "tic" marks (') always enclose a single CHARACTER, while double quotes (")
  3241. always enclose an array of CHARACTERs, that is, a STRING.
  3242. 1HPlease type a space to go on, or B or Q to go back to the question.              2553 311B302$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                ARRAY OPERATORS
  3243.  
  3244. The operator & concatenates any two arrays of the same element type, including
  3245. two STRINGs.  It can also concatenate a single element with an array of that
  3246. element type, or two single elements into an array of length two.  For example,
  3247. every use of & below is legal:
  3248.  
  3249.            C, D : CHARACTER := '*';
  3250.            S2   : STRING(1 .. 2);
  3251.            S3   : STRING(1 .. 3) := (others => ' ');
  3252.            S5   : STRING(1 .. 5);
  3253.  
  3254.            type VECTOR is array(INTEGER range <>) of FLOAT;
  3255.            F, G : FLOAT := 1.2;
  3256.            V2   : VECTOR(1 .. 2);
  3257.            V3   : VECTOR(1 .. 3) := (others => 0.0);
  3258.            V5   : VECTOR(1 .. 5);
  3259.            ...
  3260.            S2 := C & D;  S5 := S2 & S3;  S3 := C & S2;  S3 := S2 & C;
  3261.            V2 := F & G;  V5 := V2 & V3;  V3 := F & V2;  V3 := V2 & F;
  3262. 1HPlease type a space to go on, or B to go back.                       3223 312B310$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The operators andorxor, and not, defined for BOOLEANs, are also defined for
  3263. one-dimensional arrays of BOOLEAN.  They operate element by element on the
  3264. arrays.  Thus, we can simulate sets in Ada.  For example, if we write
  3265.  
  3266.     type SET_OF_CHARS is array(CHARACTER) of BOOLEAN;
  3267.     S1 : SET_OF_CHARS := SET_OF_CHARS'('*' | '#' => TRUE, others => FALSE);
  3268.     S2 : SET_OF_CHARS := SET_OF_CHARS'('*' | '?' => TRUE, others => FALSE);
  3269.  
  3270. then S1 or S2 is SET_OF_CHARS'('*' | '#' | '?' => TRUE, others => FALSE);,
  3271. and S1 and S2 is SET_OF_CHARS'('*' => TRUE, others => FALSE);.
  3272.  
  3273. The operators = and /= can compare two records or two arrays of the same type.
  3274. Records are equal if each of their corresponding fields are equal, arrays, if
  3275. each of their corresponding elements are equal.  Arrays of different lengths
  3276. are always unequal.  The four remaining relational operators can compare two
  3277. arrays of the same type.  They're compared element by element until a
  3278. difference is found.  For example, if we have
  3279.  
  3280.                         S : STRING(1 .. 6) := "to all";
  3281.                         T : STRING(1 .. 7) := "to Bill";
  3282.  
  3283. then S > T because 'a' > 'B' in Ada's definition of type CHARACTER.
  3284. 1HPlease type a space to go on, or B to go back.                                                     2713 313B311$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   OUTSIDE ASSIGNMENT 3 - EXERCISE IN RECORDS
  3285.  
  3286. Your third Outside Assignment is to write a function specified by
  3287.  
  3288.      type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  3289.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  3290.      type DATE is
  3291.         record
  3292.            DAY   : DAY_SUBTYPE;
  3293.            MONTH : MONTH_TYPE;
  3294.            YEAR  : INTEGER;
  3295.         end record;
  3296.      function TOMORROW(TODAY : in DATE) return DATE;
  3297.  
  3298. Given any date, TOMORROW should return the following date.  Your function will
  3299. be tested only with legal dates.  As with Outside Assignment 2, a test driver
  3300. is already written; it's in NEXTDATE.ADA.  A listing is on page 12 of your
  3301. printed course notes, but you needn't understand the test driver.  If your
  3302. function fails any test, you'll see the test case, the answer from your
  3303. function, and the right answer.  Otherwise, you'll see "Congratulations, you
  3304. completed the assignment!"
  3305. 1HPlease type a space to go on, or B to go back.                                                               3029 314B312$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The definitions of MONTH_TYPE, DAY_SUBTYPE, and DATE are in the test driver;
  3306. you shouldn't define them inside your function.  A dummy solution is in
  3307. TOMORROW.DUM; it looks like this:
  3308.  
  3309.                -- Dummy solution to Outside Assignment 3
  3310.                separate (NEXTDATE)
  3311.                function TOMORROW(TODAY : in DATE) return DATE is
  3312.                begin
  3313.                   return TODAY;
  3314.                end TOMORROW;
  3315.  
  3316. Again, you'll probably want to remove or change the comment line, and you
  3317. shouldn't change the lines highlighted above.  You may, but don't have to,
  3318. include ANSWER : DATE; in the declarative region and make return ANSWER; the
  3319. last statement before end TOMORROW;.
  3320.  
  3321. Normally, years divisible by 4 are leap years.  But if a year is divisible by
  3322. 100, it must also be divisible by 400 to be a leap year.  Thus, 2000 is a leap
  3323. year, but 1900 and 2100 are not.  Note that TODAY.YEAR is divisible by 4 if and
  3324. only if TODAY.YEAR mod 4 = 0.  You can assume that TODAY.YEAR will always be
  3325. between 1583 and 3999, because outside this range the calendar gets more
  3326. complicated.
  3327. 1HPlease type a space to go on, or B to go back.                                               2512 315B313$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The steps to follow for Outside Assignment 3 are very similar to those of
  3328. Outside Assignment 2.  They're in your printed course notes on page 13:
  3329.  
  3330. 1.  Compile the test driver NEXTDATE.ADA.  Also, make a copy of the dummy
  3331.     solution by typing COPY TOMORROW.DUM TOMORROW.ADA.  You need do this step
  3332.     only once.
  3333.  
  3334. 2.  Edit TOMORROW.ADA to become your real solution.  You can skip this step the
  3335.     first time through, to see error messages from the test driver.
  3336.  
  3337. 3.  Compile TOMORROW.ADA.  If there are compiler errors, go back to step 2.
  3338.  
  3339. 4.  Link with the name of the main program NEXTDATE.  Then execute.  If the
  3340.     test driver prints error messages, go back to step 2.
  3341.  
  3342. 5.  When the message "Congratulations, you completed the assignment!" is
  3343.     printed, you'll have a chance to compare your solution with ours.
  3344. 1HPlease type a space to go on, or B to go back.                                                                3119 316B314$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$There are many ways to solve this problem.  In our solution we declared an
  3345. array of DAY_SUBTYPE with subscripts of type MONTH_TYPE.  Some students use a
  3346. case construct on TODAY.MONTH; some use an if block with elsifs.
  3347.  
  3348. This assignment should be a simple exercise in records.  Our solution fits on
  3349. one screen.  If your solution starts to get long and difficult, you should
  3350. think the problem through again.  Don't try to save the computer a few
  3351. microseconds; computers are supposed to save people time.  Instead, minimize
  3352. the complexity of the program to save yourself programming effort.
  3353.  
  3354. Remember that an entire record can be assigned in one statement.  Also, try to
  3355. calculate the number of days in the month and then test for end of month and
  3356. end of year in only one place.  This is better than having several blocks of
  3357. code testing for end of month and end of year in three or four different places
  3358. in your program.  One last hint: remember that MONTH_TYPE'SUCC(TODAY.MONTH)
  3359. will raise a CONSTRAINT_ERROR if TODAY.MONTH is DEC.
  3360.  
  3361. Please type X to exit ADA-TUTR temporarily, and try Outside Assignment 3.  Work
  3362. at your own pace; there's no deadline.  Good luck!
  3363. 1HPlease type X to exit, a space to go on, or B to go back.                                                         2645 317B315$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 3!
  3364.  
  3365. -- Our solution to Outside Assignment 3 (in TOMORROW.ANS):
  3366. separate (NEXTDATE)
  3367. function TOMORROW(TODAY : in DATE) return DATE is
  3368.    LENGTH : array(MONTH_TYPE) of DAY_SUBTYPE :=
  3369.                (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  3370.    ANSWER : DATE;
  3371. begin
  3372.    if TODAY.YEAR mod 4 = 0 and
  3373.         (TODAY.YEAR mod 100 /= 0 or TODAY.YEAR mod 400 = 0) then
  3374.       LENGTH(FEB) := 29;
  3375.    end if;
  3376.    if TODAY.DAY /= LENGTH(TODAY.MONTH) then                -- Not end of month.
  3377.       ANSWER := (TODAY.DAY + 1, TODAY.MONTH, TODAY.YEAR);
  3378.    elsif TODAY.MONTH /= DEC then          -- End of month, but not end of year.
  3379.       ANSWER := (1, MONTH_TYPE'SUCC(TODAY.MONTH), TODAY.YEAR);
  3380.    else                                                         -- End of year.
  3381.       ANSWER := (1, JAN, TODAY.YEAR + 1);
  3382.    end if;
  3383.    return ANSWER;
  3384. end TOMORROW;
  3385. 1HPlease type a space to go on, or B to go back.                               2760 318B316$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In our solution, the first if statement checks for leap year.  We made use of
  3386. the fact that the locally declared array LENGTH is re-initialized every time
  3387. the function is called.  After this if statement, the number of days in the
  3388. month is in LENGTH(TODAY.MONTH), and it's easy to test for end of month and end
  3389. of year - in only one place in the program.
  3390.  
  3391. We could have written MONTH_TYPE'LAST instead of DEC, and MONTH_TYPE'FIRST
  3392. instead of JAN.  We could even have used DAY_SUBTYPE'FIRST.  But the author
  3393. reasoned that if our calendar ever changes, the entire program will probably
  3394. have to be rewritten anyway!  The program seems a little easier to read when we
  3395. use the names DEC and JAN and the number 1 directly.
  3396.  
  3397. Your solution might be entirely different from ours.  It the test driver said
  3398. "Congratulations, you completed the assignment!" you can consider your solution
  3399. correct.  Let's go on to discuss recursion.
  3400. 1HPlease type a space to go on, or B to go back.                2852 319B317$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   RECURSION
  3401.  
  3402. Ada procedures and functions may call themselves, directly or indirectly.  This
  3403. process is called recursion.  While recursion often uses a little extra memory
  3404. and execution time, for certain types of problems it pays large dividends in
  3405. program simplicity.  That's a very worthwhile exchange!
  3406.  
  3407. For example, let's write a function to compute the factorial of a positive
  3408. integer.  The factorial of an integer is the product of all the integers from
  3409. that number down to one.  Thus, FACTORIAL(5) = 5 * 4 * 3 * 2 * 1 = 120.
  3410. Although we could easily write this function with a for loop, we'll use
  3411. recursion instead.  Note that if N = 1, then FACTORIAL(N) = 1; otherwise,
  3412. FACTORIAL(N) = N * FACTORIAL(N - 1).
  3413.  
  3414.              function FACTORIAL(N : in POSITIVE) return POSITIVE is
  3415.                 ANSWER : POSITIVE := 1;
  3416.              begin
  3417.                 if N > 1 then
  3418.                    ANSWER := N * FACTORIAL(N - 1);
  3419.                 end if;
  3420.                 return ANSWER;
  3421.              end FACTORIAL;
  3422. 1HPlease type a space to go on, or B to go back.                        3020 320B318$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             function FACTORIAL(N : in POSITIVE) return POSITIVE is
  3423.                 ANSWER : POSITIVE := 1;
  3424.              begin
  3425.                 if N > 1 then
  3426.                    ANSWER := N * FACTORIAL(N - 1);
  3427.                 end if;
  3428.                 return ANSWER;
  3429.              end FACTORIAL;
  3430.  
  3431. The highlighted line shows where this function calls itself.  Recursive
  3432. subprograms always call themselves conditionally; otherwise the program would
  3433. run out of memory, no matter how large the machine.  Here the recursive call is
  3434. inside an if block.
  3435.  
  3436. Note that ANSWER is initialized to 1.  If the function is called with N = 1,
  3437. the if statement is FALSE, ANSWER isn't modified, and 1 is returned as the
  3438. value of the function.  If the function is called with N = 2, the if statement
  3439. is TRUE, and the highlighted line is executed.  The machine starts to compute
  3440. the expression as 2 * ..., and then FACTORIAL is called with N = 1.  It's as if
  3441. the machine made another copy of the code for FACTORIAL and called that.
  3442. Actually there's only one copy of the code, but the machine maintains multiple
  3443. pointers to it.
  3444. 1HPlease type a space to go on, or B to go back.                                                        2866 321B319$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             function FACTORIAL(N : in POSITIVE) return POSITIVE is
  3445.                 ANSWER : POSITIVE := 1;
  3446.              begin
  3447.                 if N > 1 then
  3448.                    ANSWER := N * FACTORIAL(N - 1);
  3449.                 end if;
  3450.                 return ANSWER;
  3451.              end FACTORIAL;
  3452.  
  3453. When the recursive call is made, the system allocates additional memory for new
  3454. versions of any local variables like ANSWER.  Also, the arguments like N are
  3455. separate for each recursive call.
  3456.  
  3457. Suppose the main program calls FACTORIAL with N = 2.  Then, in computing the
  3458. expression, FACTORIAL calls itself with N = 1.  In this second call, a new
  3459. local variable ANSWER is created, separate from the one in the first call.
  3460. Also, argument N is 1 in the second call, but 2 in the first call.  In the
  3461. second call, the if statement is FALSE, and 1 is returned.  In the first call,
  3462. the calculation of the expression is completed, using the value 1 returned by
  3463. the second call.  Thus, ANSWER becomes 2 * 1 = 2, and the first call returns
  3464. the answer 2 to the main program.
  3465. 1HPlease type a space to go on, or B to go back.          3012 322B320$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             function FACTORIAL(N : in POSITIVE) return POSITIVE is
  3466.                 ANSWER : POSITIVE := 1;
  3467.              begin
  3468.                 if N > 1 then
  3469.                    ANSWER := N * FACTORIAL(N - 1);
  3470.                 end if;
  3471.                 return ANSWER;
  3472.              end FACTORIAL;
  3473.  
  3474. If the main program calls FACTORIAL with N = 3, the function starts to compute
  3475. the expression as ANSWER := 3 * ..., and calls FACTORIAL with N = 2.  In this
  3476. second call, the function starts to compute ANSWER := 2 * ..., and calls
  3477. FACTORIAL with N = 1.  In this third call, the if statement is FALSE, and the
  3478. answer 1 is returned to the second call.  The second call finishes the
  3479. computation of the expression ANSWER := 2 * 1, and returns the answer 2 to the
  3480. first call.  Finally, the first call finishes computing the expression with
  3481. ANSWER := 3 * 2, and returns the answer 6 to the main program.
  3482.  
  3483. This simple function wouldn't have been complicated even without recursion.  In
  3484. a moment we'll discuss the Tower of Hanoi problem.  The recursive solution is
  3485. very simple, but a solution without recursion would be very complicated indeed.
  3486. 1HPlease type a space to go on, or B to go back.                                                                24502323032413243324B321$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In this question, function A calls B, and B conditionally calls A.  The
  3487. specification of function B is given early so that A can call it.
  3488.  
  3489.                  function B (I : in INTEGER) return INTEGER;
  3490.  
  3491.                  function A (I : in INTEGER) return INTEGER is
  3492.                  begin
  3493.                     return B(I - 1) + 1;
  3494.                  end A;
  3495.  
  3496.                  function B (I : in INTEGER) return INTEGER is
  3497.                     ANS : INTEGER := 0;
  3498.                  begin
  3499.                     if I > 0 then
  3500.                        ANS := A(I);
  3501.                     end if;
  3502.                     return ANS;
  3503.                  end B;
  3504.  
  3505. If the main program calls function A with an argument equal to 2, what value
  3506. will A return:  0, 1, 2, or 3?  You may need pencil and paper to figure this
  3507. one out.
  3508. 1HPlease press 0, 1, 2, or 3, or B to go back.                          2628 325B322Q322$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 function B (I : in INTEGER) return INTEGER;
  3509.  
  3510.                  function A (I : in INTEGER) return INTEGER is
  3511.                  begin
  3512.                     return B(I - 1) + 1;
  3513.                  end A;
  3514.  
  3515.                  function B (I : in INTEGER) return INTEGER is
  3516.                     ANS : INTEGER := 0;
  3517.                  begin
  3518.                     if I > 0 then
  3519.                        ANS := A(I);
  3520.                     end if;
  3521.                     return ANS;
  3522.                  end B;
  3523.  
  3524. You're right!  When the main program calls A(2), A starts to evaluate
  3525. B(1) + 1.  The if statement in B is TRUE, so B simply calls A(1).  The call
  3526. A(1) starts to evaluate B(0) + 1.  The if statement in this call to B is FALSE,
  3527. so B(0) simply returns 0, and the call A(1) returns 0 + 1 = 1.  The call B(1)
  3528. returns the same answer, so the call A(2) returns 1 + 1 = 2.
  3529. 1HPlease type a space to go on, or B or Q to go back to the question.                                                2574 325B322Q322$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                 function B (I : in INTEGER) return INTEGER;
  3530.  
  3531.                  function A (I : in INTEGER) return INTEGER is
  3532.                  begin
  3533.                     return B(I - 1) + 1;
  3534.                  end A;
  3535.  
  3536.                  function B (I : in INTEGER) return INTEGER is
  3537.                     ANS : INTEGER := 0;
  3538.                  begin
  3539.                     if I > 0 then
  3540.                        ANS := A(I);
  3541.                     end if;
  3542.                     return ANS;
  3543.                  end B;
  3544.  
  3545. No, when the main program calls A(2), A starts to evaluate B(1) + 1.  The if
  3546. statement in B is TRUE, so B simply calls A(1).  The call A(1) starts to
  3547. evaluate B(0) + 1.  The if statement in this call to B is FALSE, so B(0) simply
  3548. returns 0, and the call A(1) returns 0 + 1 = 1.  The call B(1) returns the same
  3549. answer, so the call A(2) returns 1 + 1 = 2.
  3550. 1HPlease type a space to go on, or B or Q to go back to the question.  3026 326B322$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                           THE TOWER OF HANOI PROBLEM
  3551.  
  3552. The "Tower of Hanoi" is a solitaire puzzle that was named when Hanoi was the
  3553. capital of a free country: French Indochina.  There are three pegs labeled A,
  3554. B, and C; one of them has a tower of N doughnut-shaped disks of decreasing
  3555. size, like this:
  3556.  
  3557.                |                       |                       |
  3558.                |                       |                       |
  3559.               =|=                      |                       |
  3560.              ==|==                     |                       |
  3561.             ===|===                    |                       |
  3562.            ====|====                   |                       |
  3563.           =====|=====                  |                       |
  3564.        -----------------       -----------------       -----------------
  3565.                A                       B                       C
  3566.  
  3567. The object is to move the entire tower from one peg to another, say, from A to
  3568. B.  Only one disk may be moved at a time, and a larger disk may never be placed
  3569. on top of a smaller one.  The shortest solution to the puzzle with N disks
  3570. requires 2**N - 1 moves.
  3571. 1HPlease type a space to go on, or B to go back.                                                  3160 327B325$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$For example, we can move five disks from A to B with the following 31 moves:
  3572. (Read them from left to right, not in columns.)
  3573.  
  3574. A to B,  A to C,  B to C,  A to B,  C to A,  C to B,  A to B,  A to C,  B to C,
  3575. B to A,  C to A,  B to C,  A to B,  A to C,  B to C,  A to B,  C to A,  C to B,
  3576. A to B,  C to A,  B to C,  B to A,  C to A,  C to B,  A to B,  A to C,  B to C,
  3577. A to B,  C to A,  C to B,  A to B.
  3578.  
  3579.                |                       |                       |
  3580.                |                       |                       |
  3581.                |                       |                       |
  3582.                |                       |                       |
  3583.               =|=                      |                       |
  3584.            ====|====                   |                       |
  3585.           =====|=====               ===|===                  ==|==
  3586.        -----------------       -----------------       -----------------
  3587.                A                       B                       C
  3588.                     (The Puzzle After the First Five Moves)
  3589.  
  3590. Writing a program to print this series of moves would be very complicated
  3591. without recursion.  Let's develop a recursive solution; we'll see that the
  3592. resulting Ada program is surprisingly simple!
  3593. 1HPlease type a space to go on, or B to go back.                3217 328B326$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$When we developed a recursive solution for the FACTORIAL function:
  3594.  
  3595.                  if N = 1,  FACTORIAL(N) = 1
  3596.                  otherwise, FACTORIAL(N) = N * FACTORIAL(N - 1)
  3597.  
  3598. we expressed FACTORIAL(N) in terms of FACTORIAL(N - 1), and gave the trivial
  3599. solution for N = 1.  The Ada program was easily written from the above.
  3600.  
  3601. For the Tower of Hanoi problem, let's develop a solution for N disks in terms
  3602. of a solution for N - 1 disks.  Suppose we want to move five disks from A to B,
  3603. using C as a spare peg.  We first move four disks from A to C, then move one
  3604. disk from A to B, and finally move four disks from C to B.  In general, to move
  3605. N disks from a source peg to a destination peg, we first move N - 1 disks from
  3606. the source to the spare, then move one disk from the source to the destination,
  3607. and finally move N - 1 disks from the spare to the destination.
  3608.  
  3609. To move the one disk from the source to the destination, our program will
  3610. simply print out the move.  To move N - 1 disks, the program will call itself.
  3611. The solution for zero disks is trivial indeed: the program will do nothing!
  3612.  
  3613. The following program is extremely simple: three executable statements inside
  3614. an if block.  Yet it can print out a very complicated series of moves!
  3615. 1HPlease type a space to go on, or B to go back.                                                           2820 329B327$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       with TEXT_IO; use TEXT_IO;
  3616.        procedure HANOI(N : in NATURAL; FROM, TO, SPARE : in CHARACTER) is
  3617.        begin
  3618.           if N > 0 then
  3619.              HANOI(N - 1, FROM, SPARE, TO);
  3620.              PUT_LINE(FROM & " to " & TO);
  3621.              HANOI(N - 1, SPARE, TO, FROM);
  3622.           end if;
  3623.        end HANOI;
  3624.  
  3625. To move five disks from A to B, using C as a spare, we would call
  3626. HANOI(5, 'A', 'B', 'C');.
  3627.  
  3628. Note that when HANOI is called with N = 0, it does nothing.  When called with
  3629. N = 1, the if statement is true, and the three lines within the if block are
  3630. executed.  But the first and third lines do nothing, because they call HANOI
  3631. with N = 0.  The second line prints, for example, A to B.
  3632.  
  3633. When called with a larger value of N, the first line within the if block moves
  3634. N - 1 disks from the source to the spare peg.  The second line prints the move
  3635. of one disk from the source to the destination, and the third line moves N - 1
  3636. disks from the spare peg to the destination.
  3637. 1HPlease type a space to go on, or B to go back.                                                        2656 330B328$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Most implementations of Ada won't allow HANOI to be a main program, because it
  3638. has arguments.  A short main program to call HANOI is shown here.  A slightly
  3639. longer program could get N and the names of the three pegs from the user.
  3640.  
  3641.                           with HANOI;
  3642.                           procedure DEMO is
  3643.                           begin
  3644.                              HANOI(5, 'A', 'B', 'C');
  3645.                           end DEMO;
  3646.  
  3647. In summary, our first example of recursion, FACTORIAL, was very simple.
  3648. However, that program would have been simple even without recursion.  Our
  3649. second example, HANOI, also was very simple, but the program would have been
  3650. quite complicated without recursion.
  3651.  
  3652. Our fourth Outside Assignment will be to write a Fibonacci function FIB, using
  3653. recursion.  As with FACTORIAL, this function would be easy to write even
  3654. without recursion.  However, as an exercise we'll write it using recursion.
  3655. 1HPlease type a space to go on, or B to go back.                    2861 331B329$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                  OUTSIDE ASSIGNMENT 4 - EXERCISE IN RECURSION
  3656.  
  3657. Your fourth Outside Assignment is to write, using recursion, a function
  3658. specified by
  3659.  
  3660.                  function FIB(N : in POSITIVE) return POSITIVE;
  3661.  
  3662. Fibonacci was a mathematician in the Middle Ages.  The so-called Fibonacci
  3663. Series is a series of integers.  Each number in the series is the sum of the
  3664. two previous numbers.  The first two Fibonacci numbers are both 1.
  3665.  
  3666.      N:    1  2  3  4  5  6   7   8   9  10  11   12   13   14   15   16 ...
  3667.    FIB(N): 1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987 ...
  3668.  
  3669. Note that if N = 1 or N = 2, then FIB(N) = 1; otherwise,
  3670. FIB(N) = FIB(N - 1) + FIB(N - 2).  Writing this function in Ada will be an easy
  3671. and short assignment.  A test driver is provided in FIBTEST.ADA; a listing is
  3672. on page 14 of your printed course notes.  As before, if all tests are passed,
  3673. it prints "Congratulations, you completed the assignment!"  If there's an
  3674. error, it prints the test case, the answer from your function, and the right
  3675. answer.
  3676. 1HPlease type a space to go on, or B to go back.               2013 332B330$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A dummy solution is in FIB.DUM.  As before, you shouldn't change the lines
  3677. highlighted here:
  3678.  
  3679.                 -- Dummy solution to Outside Assignment 4
  3680.                 separate (FIBTEST)
  3681.                 function FIB(N : in POSITIVE) return POSITIVE is
  3682.                 begin
  3683.                    return 4;
  3684.                 end FIB;
  3685.  
  3686.  
  3687. The steps to follow for Outside Assignment 4 are similar to those of the last
  3688. two Outside Assignments.  They're in your printed course notes on page 15:
  3689. 1HPlease type a space to go on, or B to go back.                                                               2454 333B331$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1.  Compile the test driver FIBTEST.ADA.  Also, make a copy of the dummy
  3690.     solution by typing COPY FIB.DUM FIB.ADA.  You need do this step only once.
  3691.  
  3692. 2.  Edit FIB.ADA to become your real solution.  You can skip this step the
  3693.     first time through, to see error messages from the test driver.
  3694.  
  3695. 3.  Compile FIB.ADA.  If there are compiler errors, go back to step 2.
  3696.  
  3697. 4.  Link with the name of the main program FIBTEST.  Then execute.  If the test
  3698.     driver prints error messages, go back to step 2.
  3699.  
  3700. 5.  When the message "Congratulations, you completed the assignment!" is
  3701.     printed, you'll have a chance to compare your solution with ours.
  3702.  
  3703.  
  3704. Please type X to exit ADA-TUTR temporarily, and try Outside Assignment 4.  Work
  3705. at your own pace; there's no deadline.  Good luck!
  3706. 1HPlease type X to exit, a space to go on, or B to go back.                      2811 334B332$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 4!
  3707.  
  3708.              -- Our solution to Outside Assignment 4 (in FIB.ANS):
  3709.              separate (FIBTEST)
  3710.              function FIB(N : in POSITIVE) return POSITIVE is
  3711.                 ANSWER : POSITIVE := 1;
  3712.              begin
  3713.                 if N > 2 then
  3714.                    ANSWER := FIB(N - 1) + FIB(N - 2);
  3715.                 end if;
  3716.                 return ANSWER;
  3717.              end FIB;
  3718.  
  3719. Your solution is probably quite similar to ours.  Perhaps you used else and
  3720. didn't initialize ANSWER in the declarative region.  Perhaps you had some other
  3721. minor variation.  Our solution is probably no "better" than yours, if the test
  3722. driver said, "Congratulations, you completed the assignment!"
  3723.  
  3724. Was this assignment too easy?  We promise that Outside Assignment 5 will be
  3725. much more challenging!  But first we need to discuss procedures and functions
  3726. in more detail, as well as packages and information hiding, access types, and
  3727. exceptions.
  3728. 1HPlease type a space to go on, or B to go back.                                                                 2620 335B333$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            PROCEDURES AND FUNCTIONS
  3729.  
  3730. When we compiled procedures HELLO and ADD into the library, we made it possible
  3731. for other units to with them and call them.  (We don't use procedures and
  3732. functions, because dot notation doesn't apply to them.)  We can also compile
  3733. just a specification, supplying the body later.  For example, we could compile
  3734.  
  3735.          function UPPER_CASE(S : in STRING) return STRING;
  3736.  
  3737. When we later write the body, it must agree with that specification:
  3738.  
  3739.          function UPPER_CASE(S : in STRING) return STRING is
  3740.             ANSWER : STRING(S'RANGE) := S;
  3741.          begin
  3742.             for I in S'RANGE loop
  3743.                if S(I) in 'a' .. 'z' then
  3744.                   ANSWER(I) := CHARACTER'VAL(CHARACTER'POS(S(I)) - 32);
  3745.                end if;
  3746.             end loop;
  3747.             return ANSWER;
  3748.          end UPPER_CASE;
  3749. 1HPlease type a space to go on, or B to go back.                                                        2613 336B334$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Functions and procedures may also be declared locally, in which case they must
  3750. follow any simple declarations like I : INTEGER; or S : STRING(1 .. 5);.
  3751.  
  3752.        with TEXT_IO; use TEXT_IO;
  3753.        procedure GREETING is
  3754.           S : STRING(1 .. 5) := "Hello";
  3755.           function UPPER_CASE(S : in STRING) return STRING is
  3756.              ANSWER : STRING(S'RANGE) := S;
  3757.           begin
  3758.              for I in S'RANGE loop
  3759.                 if S(I) in 'a' .. 'z' then
  3760.                    ANSWER(I) := CHARACTER'VAL(CHARACTER'POS(S(I)) - 32);
  3761.                 end if;
  3762.              end loop;
  3763.             return ANSWER;
  3764.           end UPPER_CASE;
  3765.        begin
  3766.           PUT_LINE(UPPER_CASE(S));
  3767.        end GREETING;
  3768.  
  3769. As we've seen, we can declare local functions and procedures to be separate.
  3770. These subprograms can in turn declare separate subprograms, to any depth:
  3771. 1HPlease type a space to go on, or B to go back.                                                               2316 337B335$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                  procedure MAIN is
  3772.                      function A return FLOAT is separate;
  3773.                   begin
  3774.                      ...
  3775.                   end MAIN;
  3776.  
  3777.                   separate (MAIN)
  3778.                   function A return FLOAT is
  3779.                      procedure B is separate;
  3780.                   begin
  3781.                      ...
  3782.                   end A;
  3783.  
  3784.                   separate (MAIN.A)
  3785.                   procedure B is
  3786.                      procedure C(I : in INTEGER) is separate;
  3787.                   begin
  3788.                      ...
  3789.                   end B;
  3790.  
  3791.                   separate (MAIN.A.B)
  3792.                   procedure C(I : in INTEGER) is ... (etc.)
  3793. 1HPlease type a space to go on, or B to go back.                                                            2764 338B336$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$However, is separate may be used only at the outermost level.  The example
  3794. below is legal as it stands, but we may not make procedure B separate unless we
  3795. make function A separate, thus bringing function A to the outermost level:
  3796.  
  3797.                          procedure MAIN is
  3798.                             F : FLOAT;
  3799.                             function A return FLOAT is
  3800.                                ANSWER : FLOAT;
  3801.                                procedure B is
  3802.                                begin
  3803.                                   ...
  3804.                                end B;
  3805.                             begin
  3806.                                ...
  3807.                                return ANSWER;
  3808.                             end A;
  3809.                          begin
  3810.                             ...
  3811.                          end MAIN;
  3812.  
  3813. A program that begins separate (...) must be compiled after the program that
  3814. says is separate, because a separate subprogram depends on its "parent."
  3815. 1HPlease type a space to go on, or B to go back.            2844 339B337$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A procedure or function specification gives the name, mode, and type of each
  3816. argument.  A function specification also gives the type of the result.  The
  3817. mode can be inout, or in out.  If the mode is omitted, it's assumed to be in.
  3818. Thus, these two lines have the same effect:
  3819.  
  3820.         procedure HANOI(N : in NATURAL; FROM, TO, SPARE : in CHARACTER);
  3821.         procedure HANOI(N : NATURAL;    FROM, TO, SPARE : CHARACTER);
  3822.  
  3823. The arguments of a function must always be of mode in, never out or in out.
  3824.  
  3825. Note that when several arguments have the same mode and type, they can be
  3826. placed in one list, separated by commas.  The lists themselves are separated by
  3827. semicolons.  This specification has the same effect as the two above:
  3828.  
  3829. procedure HANOI(N : NATURAL; FROM: CHARACTER; TO: CHARACTER; SPARE: CHARACTER);
  3830.  
  3831. In any event, the arguments in a call to a procedure or function are always
  3832. separated by commas:
  3833.  
  3834.                             HANOI(5, 'A', 'B', 'C');
  3835. 1HPlease type a space to go on, or B to go back.                                16544340134123423343B338$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   1.  procedure P(A; B; C : in INTEGER);
  3836.  
  3837.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3838.  
  3839.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3840.  
  3841.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);
  3842.  
  3843.  
  3844. Which one of the above is legal?
  3845. 1HPlease press 1, 2, 3, or 4, or B to go back.                      2318 344B339Q339$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   1.  procedure P(A; B; C : in INTEGER);
  3846.  
  3847.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3848.  
  3849.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3850.  
  3851.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);
  3852.  
  3853. You're right!  In a subprogram specification, the items of a list are separated
  3854. by commas, and the lists are separated by semicolons.  In a list, the mode may
  3855. be omitted; it's assumed to be in.
  3856.  
  3857. In number 1, the items should be separated by commas.  Number 2 has a return
  3858. clause in a procedure specification, and number 3 has a mode other than in in a
  3859. function specification.
  3860. 1HPlease type a space to go on, or B or Q to go back to the question.                                                          2074 344B339Q339$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   1.  procedure P(A; B; C : in INTEGER);
  3861.  
  3862.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3863.  
  3864.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3865.  
  3866.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);
  3867.  
  3868. No, in number 1 the items should be separated by commas, not semicolons.  In a
  3869. subprogram specification, the items in a list are separated by commas, and the
  3870. lists are separated by semicolons.  Here a "list" means a collection of
  3871. arguments sharing the same mode and type (in INTEGER).
  3872. 1HPlease type a space to go on, or B or Q to go back to the question.  1836 344B339Q339$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   1.  procedure P(A; B; C : in INTEGER);
  3873.  
  3874.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3875.  
  3876.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3877.  
  3878.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);
  3879.  
  3880. No, number 2 is illegal because a return clause applies only to a function
  3881. specification, not a procedure specification.
  3882. 1HPlease type a space to go on, or B or Q to go back to the question.                                        1757 344B339Q339$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   1.  procedure P(A; B; C : in INTEGER);
  3883.  
  3884.    2.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3885.  
  3886.    3.  function  F(A, B, C : INTEGER; D, E : in out FLOAT) return CHARACTER;
  3887.  
  3888.    4.  procedure P(A, B, C : INTEGER; D, E : in out FLOAT);
  3889.  
  3890. No, number 3 is illegal because all arguments of a function must have mode in.
  3891. 1HPlease type a space to go on, or B or Q to go back to the question.                   3111 345B339$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               DEFAULT PARAMETERS
  3892.  
  3893. The in parameters of a subprogram specification may be given default values.
  3894. Suppose, for example, that the package INTEGER_IO is instantiated for the type
  3895. INTEGER.  Here's a simplified version of the specification for the procedure
  3896. PUT (the actual specification can be found in section 14.3.10 of the LRM):
  3897.  
  3898.                     procedure PUT(ITEM  : in INTEGER;
  3899.                                   WIDTH : in INTEGER := 6;
  3900.                                   BASE  : in INTEGER := 10);
  3901.  
  3902. This means that, in calls to PUT, the WIDTH and BASE arguments are optional.
  3903. If WIDTH is omitted, it's assumed to be 6, and if BASE is omitted, it's assumed
  3904. to be 10.  If either of these arguments is given in the call, the default value
  3905. is overridden.  (The default value for WIDTH is shown here as 6.  Actually, it
  3906. depends on the implementation of Ada.  Of course, the default value for BASE is
  3907. always 10.)
  3908.  
  3909. Default parameters let us make our Ada subprograms both flexible and easy to
  3910. use.  In other languages, we'd often have to choose between these two
  3911. qualities.  For example, suppose J is an integer.  Here are some calls to PUT:
  3912. 1HPlease type a space to go on, or B to go back.                                                                 3114 346B344$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    procedure PUT(ITEM  : in INTEGER;
  3913.                                   WIDTH : in INTEGER := 11;
  3914.                                   BASE  : in INTEGER := 10);
  3915.  
  3916.                     PUT(J);
  3917.                     PUT(J, WIDTH => 4);
  3918.                     PUT(J, BASE => 16);
  3919.                     PUT(J, BASE => 16, WIDTH => 4);
  3920.  
  3921. The first argument in each call could have been given as ITEM => J, but
  3922. everyone remembers that the first argument of PUT is the item, so named
  3923. notation seems unnecessary for this argument.  However, WIDTH and BASE are used
  3924. less frequently.  We used named notation for these arguments so the reader of
  3925. our code wouldn't have to remember which argument comes second and which comes
  3926. third.  Note that if we omit the second argument and specify the third, we must
  3927. use named notation for the third argument; we're not allowed to write
  3928. PUT(J, ,16); as in some languages.
  3929.  
  3930. If we were writing PUT in another language, we'd have to choose either making
  3931. the user specify the width and the base in every call, giving flexibility, or
  3932. writing PUT with only one argument, giving ease of use.  In Ada, default
  3933. parameters give us both flexibility and ease of use!
  3934. 1HPlease type a space to go on, or B to go back.                                                              2616 347B345$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$TEXT_IO.NEW_LINE has one parameter, SPACING, defaulted to 1.  Thus, we can call
  3935. NEW_LINE; to get one CR-LF, or, for example, NEW_LINE(3); to get three.
  3936.  
  3937. Default values may also be given in record definitions.  If we write
  3938.  
  3939.      type MONTH_TYPE is (JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC);
  3940.      subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  3941.      type DATE is
  3942.         record
  3943.            DAY   : DAY_SUBTYPE;
  3944.            MONTH : MONTH_TYPE;
  3945.            YEAR  : INTEGER := 1776;
  3946.         end record;
  3947.      USA : DATE;
  3948.  
  3949. then USA.YEAR is set to 1776 when the line declaring USA is elaborated.  Every
  3950. time an object of type DATE is declared, its YEAR field is set to 1776.
  3951. However, there's a difference between default values in records and default
  3952. parameters in subprograms.  We can't write USA := (4, JUL); all three fields of
  3953. the record must be specified.
  3954. 1HPlease type a space to go on, or B to go back.                                                            1744234813493350B346$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    procedure PUT(ITEM  : in INTEGER;
  3955.                                   WIDTH : in INTEGER := 11;
  3956.                                   BASE  : in INTEGER := 10);
  3957.  
  3958. Which one of these is legal?
  3959.  
  3960.                           1.  PUT(ITEM => 23, 5, 10);
  3961.  
  3962.                           2.  PUT(23, 5);
  3963.  
  3964.                           3.  PUT(23; 5; 10);
  3965. 1HPlease press 1, 2, or 3, or B to go back.                                2063 351B347Q347$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    procedure PUT(ITEM  : in INTEGER;
  3966.                                   WIDTH : in INTEGER := 11;
  3967.                                   BASE  : in INTEGER := 10);
  3968.  
  3969.  
  3970.                           1.  PUT(ITEM => 23, 5, 10);
  3971.  
  3972.                           2.  PUT(23, 5);
  3973.  
  3974.                           3.  PUT(23; 5; 10);
  3975.  
  3976.  
  3977. You're right!  The third argument may be omitted because it has a default
  3978. value.  In number 1, positional notation follows named, which isn't allowed,
  3979. and in number 3, the separators should be commas.
  3980. 1HPlease type a space to go on, or B or Q to go back to the question.             1848 351B347Q347$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    procedure PUT(ITEM  : in INTEGER;
  3981.                                   WIDTH : in INTEGER := 11;
  3982.                                   BASE  : in INTEGER := 10);
  3983.  
  3984.  
  3985.                           1.  PUT(ITEM => 23, 5, 10);
  3986.  
  3987.                           2.  PUT(23, 5);
  3988.  
  3989.                           3.  PUT(23; 5; 10);
  3990.  
  3991.  
  3992. No, number 1 is illegal because positional notation may not follow named.
  3993. 1HPlease type a space to go on, or B or Q to go back to the question.                            1918 351B347Q347$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    procedure PUT(ITEM  : in INTEGER;
  3994.                                   WIDTH : in INTEGER := 11;
  3995.                                   BASE  : in INTEGER := 10);
  3996.  
  3997.  
  3998.                           1.  PUT(ITEM => 23, 5, 10);
  3999.  
  4000.                           2.  PUT(23, 5);
  4001.  
  4002.                           3.  PUT(23; 5; 10);
  4003.  
  4004.  
  4005. No, number 3 is illegal because in a call, the arguments are always separated
  4006. with commas, not semicolons.
  4007. 1HPlease type a space to go on, or B or Q to go back to the question.                                                          2856 352B347$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    PACKAGES
  4008.  
  4009. package lets us group related declarations, procedures, and functions.  A
  4010. program can with the package and gain access to all of these.  However, as
  4011. we'll see, packages have many other advantages.  Usually library units are
  4012. packages rather than individual procedures and functions.
  4013.  
  4014. By way of example, consider a very simple procedure and a very simple function:
  4015.  
  4016.           procedure DOUBLE(NUMBER : in INTEGER; ANSWER : out INTEGER);
  4017.           function TWICE(NUMBER : in INTEGER) return INTEGER;
  4018.  
  4019. We could compile these individually, or we could put them in a package and
  4020. compile that instead.  Here's the package specification:
  4021.  
  4022.         package SIMPLE_MATH is
  4023.            procedure DOUBLE(NUMBER : in INTEGER; ANSWER : out INTEGER);
  4024.            function TWICE(NUMBER : in INTEGER) return INTEGER;
  4025.         end SIMPLE_MATH;
  4026.  
  4027. The package body must contain the bodies of all the procedures and functions
  4028. declared in the package specification:
  4029. 1HPlease type a space to go on, or B to go back.                    2522 353B351$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       package body SIMPLE_MATH is
  4030.           procedure DOUBLE(NUMBER : in INTEGER; ANSWER : out INTEGER) is
  4031.           begin
  4032.              ANSWER := NUMBER * 2;
  4033.           end DOUBLE;
  4034.  
  4035.           function TWICE(NUMBER : in INTEGER) return INTEGER is
  4036.           begin
  4037.              return NUMBER * 2;
  4038.           end TWICE;
  4039.        end SIMPLE_MATH;
  4040.  
  4041. The package body could optionally declare either or both subprograms to be
  4042. separate:
  4043.  
  4044.   package body SIMPLE_MATH is
  4045.      procedure DOUBLE(NUMBER : in INTEGER; ANSWER : out INTEGER) is separate;
  4046.      function TWICE(NUMBER : in INTEGER) return INTEGER is separate;
  4047.   end SIMPLE_MATH;
  4048.  
  4049. Here's an example of a calling program that withs the package and makes use of
  4050. the two subprograms declared in the package specification:
  4051. 1HPlease type a space to go on, or B to go back.                                                      2936 354B352$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     with SIMPLE_MATH; use SIMPLE_MATH;
  4052.      procedure PACKAGE_DEMO is
  4053.         I, J : INTEGER;
  4054.      begin
  4055.         I := 10;
  4056.         DOUBLE(NUMBER => I, ANSWER => J);  -- This line sets J to 20.
  4057.         J := TWICE(I);                     -- This line also sets J to 20.
  4058.      end PACKAGE_DEMO;
  4059.  
  4060. The package specification must be compiled first, but either the calling
  4061. program or the package body may be compiled second.  The calling program
  4062. depends only on the package specification, not the package body.  Similarly,
  4063. the package body depends on the package specification.  If the package body
  4064. declares any subprograms to be separate, these must be compiled after the
  4065. package body, because any separate subprogram depends on its "parent."
  4066.  
  4067. A package specification that declares no subprograms (only objects, types,
  4068. etc.) doesn't need a package body.
  4069.  
  4070. The main program can never be inside a package.  It must be a procedure
  4071. compiled directly into the library, such as HELLO or ADD.  In most
  4072. implementations of Ada, that procedure can't have any arguments.
  4073. 1HPlease type a space to go on, or B to go back.                                        2528 355B353$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A package body may optionally have initialization code, introduced by the word
  4074. begin.  This code is executed only once, the first time another program
  4075. elaborates the package by withing it.  For example, this package uses
  4076. initialization code to initialize the array B:
  4077.  
  4078.                package P is
  4079.                   function F;
  4080.                end P;
  4081.  
  4082.                package body P is
  4083.                   A : array(1 .. 10) of FLOAT := (others => 0.0);
  4084.                   B : array(1 .. 10, 1 .. 10) of INTEGER;
  4085.                   function F is
  4086.                      ...
  4087.                   end F;
  4088.                begin
  4089.                   for I in 1 .. 10 loop
  4090.                      for J in 1 .. 10 loop
  4091.                         B(I, J) := I*J*J;
  4092.                      end loop;
  4093.                   end loop;
  4094.                end P;
  4095. 1HPlease type a space to go on, or B to go back.                                                3071 356B354$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Declarations made inside a package specification are said to be exported and
  4096. are available to programs outside the package that with the package.  However,
  4097. declarations made inside the package body are available only inside the
  4098. package.  The package body doesn't even have to be written before outside
  4099. programs that with the package.  In this example, programs outside and inside
  4100. the package may use type ANSWER, array A, and procedure R, but only procedures
  4101. P, Q and R may use type QUESTION and array B.  Procedure P may be called only
  4102. by Q and R (and itself), and procedure Q is available only to R (and itself).
  4103.  
  4104.                       package X is
  4105.                          type ANSWER is (YES, NO, MAYBE);
  4106.                          A : array(1 .. 10) of FLOAT;
  4107.                          procedure R;
  4108.                       end X;
  4109.  
  4110.                       package body X is
  4111.                          type QUESTION is (WHY, WHO, HOW);
  4112.                          B : array(1 .. 10) of INTEGER;
  4113.                          procedure P is separate;
  4114.                          procedure Q is separate;
  4115.                          procedure R is separate;
  4116.                       end X;
  4117. 1HPlease type a space to go on, or B to go back.     2157T357F358B355$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      package X is
  4118.                          type ANSWER is (YES, NO, MAYBE);
  4119.                          A : array(1 .. 10) of FLOAT;
  4120.                          procedure R;
  4121.                       end X;
  4122.  
  4123.                       package body X is
  4124.                          type QUESTION is (WHY, WHO, HOW);
  4125.                          B : array(1 .. 10) of INTEGER;
  4126.                          procedure P is separate;
  4127.                          procedure Q is separate;
  4128.                          procedure R is separate;
  4129.                       end X;
  4130.  
  4131. True or False?  In this example, procedure P may call R.
  4132. 1HPlease press T for true or F for false, or B to go back.                   2344 359B356Q356$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      package X is
  4133.                          type ANSWER is (YES, NO, MAYBE);
  4134.                          A : array(1 .. 10) of FLOAT;
  4135.                          procedure R;
  4136.                       end X;
  4137.  
  4138.                       package body X is
  4139.                          type QUESTION is (WHY, WHO, HOW);
  4140.                          B : array(1 .. 10) of INTEGER;
  4141.                          procedure P is separate;
  4142.                          procedure Q is separate;
  4143.                          procedure R is separate;
  4144.                       end X;
  4145.  
  4146. You're right!  R is declared in the package specification, so any program
  4147. inside X (and any program outside X that withs the package) may call R.
  4148. 1HPlease type a space to go on, or B or Q to go back to the question.                                2329 359B356Q356$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      package X is
  4149.                          type ANSWER is (YES, NO, MAYBE);
  4150.                          A : array(1 .. 10) of FLOAT;
  4151.                          procedure R;
  4152.                       end X;
  4153.  
  4154.                       package body X is
  4155.                          type QUESTION is (WHY, WHO, HOW);
  4156.                          B : array(1 .. 10) of INTEGER;
  4157.                          procedure P is separate;
  4158.                          procedure Q is separate;
  4159.                          procedure R is separate;
  4160.                       end X;
  4161.  
  4162. True.  R is declared in the package specification, so any program inside X (and
  4163. any program outside X that withs the package) may call R.
  4164. 1HPlease type a space to go on, or B or Q to go back to the question.                                               2944 360B356$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         FUNCTIONS WITH INFIX NOTATION
  4165.  
  4166.                   +   -   *   /   **   &   =   <   >   <=   >=
  4167.  
  4168.                      and   or   xor   abs   not   mod   rem
  4169.  
  4170. Ada allows us to overload any of the above operators by enclosing the operator
  4171. in quotes following the word function.  For example, having defined type DATE,
  4172. we may want to define what it means for one date to be "less than" another.  We
  4173. could write function "<"(LEFT, RIGHT : in DATE) return BOOLEAN;.  Then, our
  4174. program could declare D1, D2 : DATE; and test if D1 < D2 then ...  This test
  4175. would call our function "<", because < is used between two objects of type
  4176. DATE.  Similarly, we can overload "*" to give the dot product of two vectors:
  4177.  
  4178.               type VECTOR is array(INTEGER range <>) of FLOAT;
  4179.               V1, V2 : VECTOR(1 .. 100);
  4180.               X : FLOAT;
  4181.               function "*"(LEFT, RIGHT : in VECTOR) return FLOAT is
  4182.                  ...
  4183.               end "*";
  4184.               ...
  4185.               X := V1 * V2;  -- This calls our function "*".
  4186. 1HPlease type a space to go on, or B to go back.                                3045 361B359$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                  +   -   *   /   **   &   =   <   >   <=   >=
  4187.  
  4188.                      and   or   xor   abs   not   mod   rem
  4189.  
  4190. There are some restrictions when using infix notation.  First, all of the
  4191. operators above (except absnot+, and -) must be used between two arguments,
  4192. and thus the function specification must have exactly two arguments.
  4193. Traditionally, the two arguments are called LEFT and RIGHT.  The operators abs
  4194. and not must have one argument on the right, and + and - may have one or two
  4195. arguments.  This restriction comes from the way the compiler handles operators.
  4196. For example, the compiler can handle X := - X;, but it's not designed to handle
  4197. X := * X;.
  4198.  
  4199. Second, the function "=" must return type BOOLEAN, its two arguments must be of
  4200. the same type, and that type must be a limited private type, to be discussed
  4201. later.  For all the types discussed so far, function "=" is already defined by
  4202. Ada.  Two records are equal if each of their corresponding fields is equal, and
  4203. two arrays are equal if they have the same length and each of their
  4204. corresponding elements is equal.
  4205. 1HPlease type a space to go on, or B to go back.                               2454 362B360$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                  +   -   *   /   **   &   =   <   >   <=   >=
  4206.  
  4207.                      and   or   xor   abs   not   mod   rem
  4208.  
  4209. Note that we can't redefine function "/=".  However, if we redefine "=" for
  4210. some limited private type, we can use /=.  Ada will call our function "=" and
  4211. negate the result.  For example,
  4212.  
  4213.           type TEXT is limited private;  -- to be discussed later
  4214.           T1, T2 : TEXT;
  4215.           function "="(LEFT, RIGHT : in TEXT) return BOOLEAN is
  4216.              ...
  4217.           end "=";
  4218.           ...
  4219.           if T1 /= T2 then  -- Calls our "=" and reverses the result.
  4220.              ...
  4221.           end if;
  4222.  
  4223. Also, we can't redefine innot inand thenor else, or :=.  Technically,
  4224. these aren't operators.
  4225. 1HPlease type a space to go on, or B to go back.                      3028 363B361$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Finally, functions using infix notation can't be compiled directly into the
  4226. library.  They must either be declared locally inside a procedure or function,
  4227. or placed inside a package.  This is done because many implementations of Ada
  4228. create files with names based on the function, procedure, or package being
  4229. compiled.  Since many of the operators are punctuation marks, they would create
  4230. file names that are incompatible with most systems.
  4231.  
  4232. For the same reason, two functions or procedures with the same name can't be
  4233. compiled directly into the library; on many systems that would attempt to give
  4234. the same name to several files.  For example, the package specification below
  4235. is legal.  However, the package body can't declare both DISPLAYs separate, and
  4236. it can't declare either "*" separate.
  4237.  
  4238.            package P is
  4239.               type COMPLEX is ...
  4240.               type VECTOR is ...
  4241.               procedure DISPLAY(C : in COMPLEX);
  4242.               procedure DISPLAY(V : in VECTOR);
  4243.               function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4244.               function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT;
  4245.            end P;
  4246. 1HPlease type a space to go on, or B to go back.                                                23532364036513653366436653666366B362$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package K is
  4247.               type COMPLEX is
  4248.                  record
  4249.                     RE, IM : FLOAT;
  4250.                  end record;
  4251.               type VECTOR is array(INTEGER range <>) of FLOAT;
  4252.               function  "+"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4253.               function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4254.               function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT;
  4255.               function  CONJUGATE(C : in COMPLEX) return COMPLEX;
  4256.               procedure DISPLAY(C : in COMPLEX);
  4257.               procedure DISPLAY(V : in VECTOR);
  4258.            end K;
  4259.  
  4260. The above is a package specification.  In the package body, how many
  4261. subprograms could be made separate:  0, 1, 2, 3, 4, 5, or 6?
  4262. 1HPlease press 0, 1, 2, 3, 4, 5, or 6, or B to go back.                       2639 367B363Q363$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       package body K is
  4263.           function  "+"(LEFT, RIGHT : in COMPLEX) return COMPLEX is ...
  4264.           function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX is ...
  4265.           function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT is ...
  4266.           function  CONJUGATE(C : in COMPLEX) return COMPLEX is separate;
  4267.           procedure DISPLAY(C : in COMPLEX) is ...
  4268.           procedure DISPLAY(V : in VECTOR) is separate;
  4269.        end K;
  4270.  
  4271.        separate (K)
  4272.        function CONJUGATE(C : in COMPLEX) return COMPLEX is
  4273.        ...
  4274.        end CONJUGATE;
  4275.  
  4276.        separate (K)
  4277.        procedure DISPLAY(V : in VECTOR) is
  4278.        ...
  4279.        end DISPLAY;
  4280.  
  4281. You're right!  Only function CONJUGATE and at most one DISPLAY can be made
  4282. separate.  Functions using infix notation can't be made separate, and the name
  4283. DISPLAY is overloaded.
  4284. 1HPlease type a space to go on, or B or Q to go back to the question.                                     2466 367B363Q363$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package K is
  4285.               type COMPLEX is
  4286.                  record
  4287.                     RE, IM : FLOAT;
  4288.                  end record;
  4289.               type VECTOR is array(INTEGER range <>) of FLOAT;
  4290.               function  "+"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4291.               function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4292.               function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT;
  4293.               function  CONJUGATE(C : in COMPLEX) return COMPLEX;
  4294.               procedure DISPLAY(C : in COMPLEX);
  4295.               procedure DISPLAY(V : in VECTOR);
  4296.            end K;
  4297.  
  4298. No, the function CONJUGATE can be made separate, because its name isn't
  4299. overloaded and it doesn't use infix notation.  Also, one, but not both, DISPLAY
  4300. procedures can be made separate.
  4301. 1HPlease type a space to go on, or B or Q to go back to the question.          2446 367B363Q363$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package K is
  4302.               type COMPLEX is
  4303.                  record
  4304.                     RE, IM : FLOAT;
  4305.                  end record;
  4306.               type VECTOR is array(INTEGER range <>) of FLOAT;
  4307.               function  "+"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4308.               function  "*"(LEFT, RIGHT : in COMPLEX) return COMPLEX;
  4309.               function  "*"(LEFT, RIGHT : in VECTOR)  return FLOAT;
  4310.               function  CONJUGATE(C : in COMPLEX) return COMPLEX;
  4311.               procedure DISPLAY(C : in COMPLEX);
  4312.               procedure DISPLAY(V : in VECTOR);
  4313.            end K;
  4314.  
  4315. No, only function CONJUGATE and at most one DISPLAY can be made separate.
  4316. Functions using infix notation can't be made separate, and the name DISPLAY is
  4317. overloaded.
  4318. 1HPlease type a space to go on, or B or Q to go back to the question.                              2349 368B363$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       INFORMATION HIDING: PRIVATE TYPES
  4319.  
  4320. Information hiding has nothing to do with secrecy; it means containing certain
  4321. programming details to a package so that the parts of the program outside the
  4322. package can't depend on them.  Thus, when these details change, other parts of
  4323. the program aren't affected.
  4324.  
  4325. Let's write the specification (only) for a graphics CRT controller package
  4326. without information hiding.  Then we'll improve on it by using a private type.
  4327.  
  4328. The package will let us create arrays in memory representing screens.  We can
  4329. create as many of these "virtual screens" as we like, and draw dots, lines, and
  4330. boxes on them in memory.  We can also display any virtual screen.  Here's the
  4331. package specification:
  4332. 1HPlease type a space to go on, or B to go back.                           2948 369B367$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$package CRT_CONTROLLER is
  4333.    type COLOR_TYPE  is (WHITE, BLACK, RED, YELLOW, GREEN, BLUE);
  4334.    type SCREEN_TYPE is array(0 .. 299, 0 .. 399) of COLOR_TYPE;
  4335.    procedure DISPLAY (SCREEN : in SCREEN_TYPE);
  4336.    procedure CLEAR   (SCREEN : in out SCREEN_TYPE; TO: in COLOR_TYPE := BLACK);
  4337.    type POINT is
  4338.       record
  4339.          ROW    : INTEGER range 0 .. 299;
  4340.          COLUMN : INTEGER range 0 .. 399;
  4341.       end record;
  4342.    procedure DOT     (SCREEN : in out SCREEN_TYPE; PLACE : in POINT;
  4343.                       COLOR : in COLOR_TYPE);
  4344.    procedure LINE    (SCREEN : in out SCREEN_TYPE; FROM, TO : in POINT;
  4345.                       COLOR : in COLOR_TYPE);
  4346.    procedure BOX     (SCREEN : in out SCREEN_TYPE; CORNER1, CORNER2 : in POINT;
  4347.                       COLOR : in COLOR_TYPE);
  4348. end CRT_CONTROLLER;
  4349.  
  4350. Note that this package assumes that the resolution of the CRT is 300 vertically
  4351. by 400 horizontally.  A screen is represented in memory by a two-dimensional
  4352. array, each element of which contains one of six possible colors.  Procedures
  4353. to draw other figures (circles, etc.) could have been added to the package.
  4354. 1HPlease type a space to go on, or B to go back.                            2817 370B368$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$That package specification makes the calling program very clear!  For example,
  4355.  
  4356.     with CRT_CONTROLLER; use CRT_CONTROLLER;
  4357.     procedure CRT_DEMO is
  4358.        S1, S2 : SCREEN_TYPE;
  4359.     begin
  4360.        CLEAR(S1);
  4361.        CLEAR(S2, TO => WHITE);
  4362.        LINE(S1, FROM => (150, 100), TO => (150, 300), COLOR => GREEN);
  4363.        DOT(S1, PLACE => (150, 200), COLOR => RED);
  4364.        DISPLAY(S1);
  4365.        BOX(S2, CORNER1 => (240, 100), CORNER2 => (60, 300), COLOR => BLUE);
  4366.        DOT(S2, PLACE => (150, 200), COLOR => YELLOW);
  4367.        DISPLAY(S2);
  4368.     end CRT_DEMO;
  4369.  
  4370. The first executable line clears memory for screen S1 to all black, because of
  4371. the default parameter in the specification of CLEAR.  The next line clears S2
  4372. to all white.  The next three lines draw a line and a dot on S1 and display S1.
  4373. The program then draws a box and a dot on S2 and displays S2.  Named notation
  4374. could optionally have been used for the first argument of each call, and for
  4375. the objects of type POINT, e.g., (ROW => 150, COLUMN => 100).
  4376. 1HPlease type a space to go on, or B to go back.                                                           1854137123723372B369$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$At a sacrifice in clarity (not recommended!), the calling program CRT_DEMO
  4377. could draw a dot in the center of screen S1 without calling DOT.  Which of the
  4378. following statements would accomplish the same thing as
  4379.  
  4380.                     DOT(S1, PLACE => (150, 200), COLOR => RED);
  4381.  
  4382.  
  4383.                 1.  S1(150, 200) := RED;
  4384.  
  4385.                 2.  S1(ROW => 150, COLUMN => 200) := RED;
  4386.  
  4387.                 3.  Either of the above would work.
  4388. 1HPlease press 1, 2, or 3, or B to go back.                      2013 373B370Q370$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    DOT(S1, PLACE => (150, 200), COLOR => RED);
  4389.  
  4390.  
  4391.                 1.  S1(150, 200) := RED;
  4392.  
  4393.                 2.  S1(ROW => 150, COLUMN => 200) := RED;
  4394.  
  4395.                 3.  Either of the above would work.
  4396.  
  4397.  
  4398. You're right!  At a sacrifice in clarity, the appropriate element of S1 can be
  4399. set directly to RED to draw a dot in the center of the screen.  Number 2 is
  4400. wrong because the names ROW and COLUMN apply to type POINT, not to subscripts
  4401. of the array.
  4402. 1HPlease type a space to go on, or B or Q to go back to the question.                                                               1758 373B370Q370$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    DOT(S1, PLACE => (150, 200), COLOR => RED);
  4403.  
  4404.  
  4405.                 1.  S1(150, 200) := RED;
  4406.  
  4407.                 2.  S1(ROW => 150, COLUMN => 200) := RED;
  4408.  
  4409.                 3.  Either of the above would work.
  4410.  
  4411.  
  4412. No, the names ROW and COLUMN apply to type POINT, not to subscripts of the
  4413. array.  For this reason number 2 won't compile.
  4414. 1HPlease type a space to go on, or B or Q to go back to the question.                  3138 374B370$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Although the calling program is very clear, there's one disadvantage that can
  4415. be eliminated by using a private type: if the resolution of the screen is
  4416. changed, the calling program is affected.  For example, the two calls to DOT
  4417. are each intended to draw a dot in the center of the screen.  These calls will
  4418. have to be changed when the resolution changes, or the dot will no longer be in
  4419. the center.  Also, nothing prevents CRT_DEMO from saying S1(150, 200) := RED;
  4420. directly, instead of calling DOT.  This is a disadvantage, because accessing
  4421. the elements of the array directly makes CRT_DEMO very susceptible to changes
  4422. in the package.
  4423.  
  4424. It would be better to force CRT_DEMO to call our procedure DOT, and make it
  4425. impossible for CRT_DEMO to use the fact the a screen is represented by a
  4426. two-dimensional array.  Then the representation of a screen can change without
  4427. affecting the correctness of CRT_DEMO.
  4428.  
  4429. We'll improve our package specification and calling program to make SCREEN_TYPE
  4430. private type, so that its details can be used only inside the package.  Since
  4431. the screen resolution won't be available outside the package, we'll normalize
  4432. ROW and COLUMN, making them floating point numbers in the range 0.0 .. 1.0.
  4433. 1HPlease type a space to go on, or B to go back.                                      2632 375B373$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Here's our improved package specification:
  4434.  
  4435. package CRT_CONTROLLER is
  4436.    type COLOR_TYPE  is (WHITE, BLACK, RED, YELLOW, GREEN, BLUE);
  4437.    type SCREEN_TYPE is private;
  4438.    procedure DISPLAY (SCREEN : in SCREEN_TYPE);
  4439.    procedure CLEAR   (SCREEN : in out SCREEN_TYPE; TO: in COLOR_TYPE := BLACK);
  4440.    type POINT is
  4441.       record
  4442.          ROW    : FLOAT range 0.0 .. 1.0;
  4443.          COLUMN : FLOAT range 0.0 .. 1.0;
  4444.       end record;
  4445.    procedure DOT     (SCREEN : in out SCREEN_TYPE; PLACE : in POINT;
  4446.                       COLOR : in COLOR_TYPE);
  4447.    procedure LINE    (SCREEN : in out SCREEN_TYPE; FROM, TO : in POINT;
  4448.                       COLOR : in COLOR_TYPE);
  4449.    procedure BOX     (SCREEN : in out SCREEN_TYPE; CORNER1, CORNER2 : in POINT;
  4450.                       COLOR : in COLOR_TYPE);
  4451. private
  4452.    type SCREEN_TYPE is array(0 .. 299, 0 .. 399) of COLOR_TYPE;
  4453. end CRT_CONTROLLER;
  4454. 1HPlease type a space to go on, or B to go back.                                            2427 376B374$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        package CRT_CONTROLLER is
  4455.            ...
  4456.            type SCREEN_TYPE is private;
  4457.            procedure DISPLAY (SCREEN : in SCREEN_TYPE);
  4458.            procedure CLEAR   (SCREEN : in out SCREEN_TYPE; ... );
  4459.            ...
  4460.         private
  4461.            type SCREEN_TYPE is array(0 .. 299, 0 .. 399) of COLOR_TYPE;
  4462.         end CRT_CONTROLLER;
  4463.  
  4464. Outside the package, there are only four things a calling program may do with
  4465. objects of a private type like SCREEN_TYPE:
  4466.  
  4467. 1.  Create them:  S1, S2 : SCREEN_TYPE;
  4468.  
  4469. 2.  Assign them:  S1 := S2;
  4470.  
  4471. 3.  Test them for equality and inequality:  if S1 = S2 ...   if S1 /= S2 ...
  4472.  
  4473. 4.  Use any procedures, functions, and infix operators provided by the package:
  4474.     CLEAR(S1);   DISPLAY(S2);   etc.
  4475. 1HPlease type a space to go on, or B to go back.                                                 2833 377B375$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        With objects of a private type, outside the package we may only:
  4476.  1.  Create     2.  Assign     3.  Test  =  /=     4.  Call package subprograms
  4477.  
  4478. Note that the calling program, outside the package, can no longer say
  4479. S1(150, 200) := RED;, because that's not one of the four things listed above.
  4480. The calling program is forced to call DOT.  The information that SCREEN_TYPE is
  4481. an array can be used by code only inside the package.  Of course, the compiler
  4482. uses this information when compiling code outside or inside the package.
  4483. That's why the definition of SCREEN_TYPE must be in the package specification,
  4484. not the body.  But the programmer isn't allowed to use this information outside
  4485. the package.
  4486.  
  4487. Inside the package there are no restrictions.  To write the bodies of the
  4488. subprograms, we'll have to use the structure of SCREEN_TYPE and write
  4489. statements similar to S1(150, 200) := RED;.
  4490.  
  4491. Here's our calling program, revised to agree with the improved package
  4492. specification:
  4493. 1HPlease type a space to go on, or B to go back.                                           3043 378B376$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   with CRT_CONTROLLER; use CRT_CONTROLLER;
  4494.    procedure CRT_DEMO is
  4495.       S1, S2 : SCREEN_TYPE;
  4496.    begin
  4497.       CLEAR(S1);
  4498.       CLEAR(S2, TO => WHITE);
  4499.       LINE(S1, FROM => (0.50.25), TO => (0.50.75), COLOR => GREEN);
  4500.       DOT(S1, PLACE => (0.50.5), COLOR => RED);
  4501.       DISPLAY(S1);
  4502.       BOX(S2, CORNER1 => (0.80.25), CORNER2 => (0.20.75), COLOR => BLUE);
  4503.       DOT(S2, PLACE => (0.50.5), COLOR => YELLOW);
  4504.       DISPLAY(S2);
  4505.    end CRT_DEMO;
  4506.  
  4507. Now, if a change is made only to the private part of the package specification,
  4508. CRT_DEMO won't have to be revised.  It will have to be recompiled, because the
  4509. Ada compiler needs the information in the private part of the package
  4510. specification.  (The linker won't link with obsolete units, but will tell us
  4511. what me must recompile.)  Also, the package body may have to be rewritten.  But
  4512. if CRT_DEMO was correct before, it will remain correct without any revision!
  4513. The effects of the change are confined to the package.  Containing the effects
  4514. of changes by means of information hiding is one of Ada's greatest features.
  4515. 1HPlease type a space to go on, or B to go back.                                 1438F379T380B377$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$True or False?  If the private part of a package specification is changed, the
  4516. calling program must be recompiled before the package body is recompiled.
  4517. 1HPlease press T for true or F for false, or B to go back.                                      1544 381B378Q378$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$You're right!  The package body and the calling program both depend on the
  4518. package specification, but not on each other.  They can be compiled in either
  4519. order after the package specification is compiled.
  4520. 1HPlease type a space to go on, or B or Q to go back to the question.                                1537 381B378Q378$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$False.  The package body and the calling program don't depend on each other,
  4521. but only on the package specification.  Thus they can be compiled in either
  4522. order after the package specification is compiled.
  4523. 1HPlease type a space to go on, or B or Q to go back to the question.                                       2439 382B378$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If a package exports a constant of a private type, the constant is declared in
  4524. the "public" part of the package specification, but it can't be assigned a
  4525. value until we get to the private part.  This is called a deferred constant.
  4526. For example,
  4527.  
  4528. package CRT_CONTROLLER is
  4529.    type COLOR_TYPE  is (WHITE, BLACK, RED, YELLOW, GREEN, BLUE);
  4530.    type SCREEN_TYPE is private;
  4531.    FLAG_OF_ITALY : constant SCREEN_TYPE;
  4532.    procedure DISPLAY (SCREEN : in SCREEN_TYPE);
  4533.    ...
  4534. private
  4535.    type SCREEN_TYPE is array(0 .. 299, 0 .. 399) of COLOR_TYPE;
  4536.    FLAG_OF_ITALY : constant SCREEN_TYPE :=
  4537.        (others => (0 .. 132 => GREEN, 133 .. 266 => WHITE, 267 .. 399 => RED));
  4538. end CRT_CONTROLLER;
  4539.  
  4540. CRT_DEMO could then say S1 := FLAG_OF_ITALY; or DISPLAY(FLAG_OF_ITALY);.
  4541. 1HPlease type a space to go on, or B to go back.                                     2950 383B381$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      TYPE TEXT AND LIMITED PRIVATE TYPES
  4542.  
  4543. Earlier we remarked that Ada strings are of fixed length.  Section 7.6 of the
  4544. LRM suggests that we create a type TEXT to get around this restriction.
  4545. Instead of declaring objects to be STRINGs, we'll declare them to be of type
  4546. TEXT, which will simulate variable-length strings.  Then we'll see how this
  4547. creates a need for limited private types.
  4548.  
  4549. The package specification in section 7.6 of the LRM makes use of discriminated
  4550. records.  Since we haven't yet covered that topic, we'll give a simplified
  4551. presentation here.  Let's declare
  4552.  
  4553.                     type TEXT is
  4554.                        record
  4555.                           LEN : INTEGER range 0 .. 80 := 0;
  4556.                           VAL : STRING(1 .. 80);
  4557.                        end record;
  4558.  
  4559. Any appropriate maximum length may be used in place of 80.  It isn't necessary
  4560. to initialize the VAL field to all blanks, because the LEN field keeps track of
  4561. how much of the VAL field is significant.  The LEN field is given a default
  4562. value of 0, so that objects of type TEXT will be initialized to empty.
  4563. 1HPlease type a space to go on, or B to go back.                          2515 384B382$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    type TEXT is
  4564.                        record
  4565.                           LEN : INTEGER range 0 .. 80 := 0;
  4566.                           VAL : STRING(1 .. 80);
  4567.                        end record;
  4568.  
  4569. For example, we could declare T1 : TEXT;.  We could then set T1.LEN := 5; and
  4570. T1.VAL(1 .. 5) := "Hello";.  The fact that the last 75 characters of T1.VAL
  4571. might contain garbage is of no consequence, because T1.LEN tells our program
  4572. to consider only the first 5 characters of T1.VAL.  Since T1.LEN is a variable,
  4573. we've simulated variable-length strings.
  4574.  
  4575. A minor disadvantage is that, for each object of type TEXT, we reserve enough
  4576. memory for the longest possible length (80 in this example).  Discriminated
  4577. records, to be covered in the Advanced Topics section, can overcome this
  4578. disadvantage.
  4579. 1HPlease type a space to go on, or B to go back.                                                             2758 385B383$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Type TEXT will be much easier to use if we write some subprograms.  First, we
  4580. need to convert between types TEXT and STRING.  Conversion in both directions
  4581. is very simple:
  4582.  
  4583.                    function STR(T : in TEXT) return STRING is
  4584.                    begin
  4585.                       return T.VAL(1 .. T.LEN);
  4586.                    end STR;
  4587.  
  4588.                    function TXT(S : in STRING) return TEXT is
  4589.                       ANSWER : TEXT;
  4590.                    begin
  4591.                       ANSWER.LEN := S'LENGTH;
  4592.                       ANSWER.VAL(1 .. ANSWER.LEN) := S;
  4593.                       return ANSWER;
  4594.                    end TXT;
  4595.  
  4596. Now we can write, for example, T1 : TEXT := TXT("Hello"); and we don't even
  4597. have to count the characters of "Hello".  Later, the program might execute
  4598. T1 := TXT("Type TEXT is very convenient."); showing that T1 simulates a
  4599. variable-length string.  If we with and use TEXT_IO in our program, we can
  4600. write PUT_LINE(STR(T1));.
  4601. 1HPlease type a space to go on, or B to go back.                  2865 386B384$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$It would be convenient to overload the & operator to concatenate two TEXTs, or
  4602. a TEXT with a STRING.  We can also overload four of the relational operators:
  4603.  
  4604.       function "&"  (LEFT, RIGHT : in TEXT)               return TEXT;
  4605.       function "&"  (LEFT : in TEXT;   RIGHT : in STRING) return TEXT;
  4606.       function "&"  (LEFT : in STRING; RIGHT : in TEXT)   return TEXT;
  4607.       function "<"  (LEFT, RIGHT : in TEXT)               return BOOLEAN;
  4608.       function ">"  (LEFT, RIGHT : in TEXT)               return BOOLEAN;
  4609.       function "<=" (LEFT, RIGHT : in TEXT)               return BOOLEAN;
  4610.       function ">=" (LEFT, RIGHT : in TEXT)               return BOOLEAN;
  4611.  
  4612. The bodies of these subprograms are very simple!  For example:
  4613.  
  4614.              function "&"(LEFT, RIGHT : in TEXT) return TEXT is
  4615.              begin
  4616.                 return TXT(STR(LEFT) & STR(RIGHT));
  4617.              end "&";
  4618.  
  4619.              function "<"(LEFT, RIGHT : in TEXT) return BOOLEAN is
  4620.              begin
  4621.                 return STR(LEFT) < STR(RIGHT);
  4622.              end "<";
  4623. 1HPlease type a space to go on, or B to go back.           1830F387T388B385$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   function TXT(S : in STRING) return TEXT is
  4624.                       ANSWER : TEXT;
  4625.                    begin
  4626.                       ANSWER.LEN := S'LENGTH;
  4627.                       ANSWER.VAL(1 .. ANSWER.LEN) := S;
  4628.                       return ANSWER;
  4629.                    end TXT;
  4630.  
  4631.  
  4632. True or False?  A call to TXT with the null string, TXT(""), will raise a
  4633. CONSTRAINT_ERROR.
  4634. 1HPlease press T for true or F for false, or B to go back.                                              2133 389B386Q386$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   function TXT(S : in STRING) return TEXT is
  4635.                       ANSWER : TEXT;
  4636.                    begin
  4637.                       ANSWER.LEN := S'LENGTH;
  4638.                       ANSWER.VAL(1 .. ANSWER.LEN) := S;
  4639.                       return ANSWER;
  4640.                    end TXT;
  4641.  
  4642.  
  4643. You're right!  The first executable statement will set ANSWER.LEN to 0, and
  4644. the second executable statement will do nothing.  The check for
  4645. CONSTRAINT_ERROR is suppressed when a null slice is involved.  Thus the
  4646. function will work correctly even for the null string.
  4647. 1HPlease type a space to go on, or B or Q to go back to the question.                                           2071 389B386Q386$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   function TXT(S : in STRING) return TEXT is
  4648.                       ANSWER : TEXT;
  4649.                    begin
  4650.                       ANSWER.LEN := S'LENGTH;
  4651.                       ANSWER.VAL(1 .. ANSWER.LEN) := S;
  4652.                       return ANSWER;
  4653.                    end TXT;
  4654.  
  4655.  
  4656. False.  The function will work correctly even for the null string.  The first
  4657. executable statement will set ANSWER.LEN to 0, and the second executable
  4658. statement will do nothing.  The check for CONSTRAINT_ERROR is suppressed when a
  4659. null slice is involved.
  4660. 1HPlease type a space to go on, or B or Q to go back to the question.     3238 390B386$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    type TEXT is
  4661.                        record
  4662.                           LEN : INTEGER range 0 .. 80 := 0;
  4663.                           VAL : STRING(1 .. 80);
  4664.                        end record;
  4665.  
  4666. There are two problems with type TEXT.  The way Ada assigns arrays is less than
  4667. ideal when assigning objects of type TEXT, and the way Ada tests for equality
  4668. is totally unacceptable.  Suppose we have T1, T2 : TEXT; and then we execute
  4669. T1 := TXT("Hello"); and then T2 := T1;.  In doing the assignment, Ada will
  4670. copy all 80 characters of T1.VAL, even though the last 75 characters contain
  4671. garbage and only the first 5 characters (and the LEN field) need be copied.
  4672. Perhaps we could live with this inefficiency, but Ada's test for equality of
  4673. arrays creates a more serious problem.
  4674.  
  4675. Suppose we execute T1 := TXT("aaaaaaaaaa"); and T2 := TXT("bbbbbbbbbb"); and
  4676. then T1 := TXT("Hello"); and T2 := TXT("Hello");.  If we now ask Ada to test
  4677. if T1 = T2, Ada will compare the entire VAL fields and conclude that T1 /= T2.
  4678. Note that T1.VAL(6 .. 10) is "aaaaa" while T2.VAL(6 .. 10) is "bbbbb", even
  4679. though only the first five characters of T1 and T2 should be considered.  (Both
  4680. LEN fields are 5.)  We of course want Ada to say that T1 = T2.
  4681. 1HPlease type a space to go on, or B to go back.                                      2932 391B389$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We could try to get around this problem by writing our own function EQUAL:
  4682.  
  4683.                function EQUAL(T1, T2 : in TEXT) return BOOLEAN is
  4684.                begin
  4685.                   return STR(T1) = STR(T2);
  4686.                end EQUAL;
  4687.  
  4688. This function would work, but we might forget to write if EQUAL(T1, T2) and
  4689. write if T1 = T2 instead.  Similarly, we could write a procedure to assign
  4690. TEXTs efficiently, and forget to use it and write T2 := T1;.  But Ada will
  4691. prevent us from assigning TEXTs and testing them for equality if we create a
  4692. package and make type TEXT limited private.  Outside the package there are
  4693. only two things we may do with objects of a limited private type:
  4694.  
  4695. 1.  Create them:  T1, T2 : TEXT;
  4696.  
  4697. 2.  Use any procedures, functions, and infix operators provided by the package:
  4698.     T1 := T1 & T2;   etc.
  4699.  
  4700. We can't test for equality and inequality unless the package includes a
  4701. function "=".  Also, Ada won't let us write T2 := T1;, but the package could
  4702. provide a procedure to assign TEXTs.  Here's our package specification:
  4703. 1HPlease type a space to go on, or B to go back.                                            2738 392B390$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             package TEXT_HANDLER is
  4704.                 type TEXT is limited private;
  4705.                 function STR(T : in TEXT) return STRING;
  4706.                 function TXT(S : in STRING) return TEXT;
  4707.                 function "&"(LEFT, RIGHT : in TEXT) return TEXT;
  4708.                 ...
  4709.                 function "="(LEFT, RIGHT : in TEXT) return BOOLEAN;
  4710.                 function "<"(LEFT, RIGHT : in TEXT) return BOOLEAN;
  4711.                 ...
  4712.                 procedure SET(TARGET : in out TEXT; TO : in TEXT);
  4713.              private
  4714.                 type TEXT is
  4715.                    record
  4716.                       LEN : INTEGER range 0 .. 80 := 0;
  4717.                       VAL : STRING(1 .. 80);
  4718.                    end record;
  4719.              end TEXT_HANDLER;
  4720.  
  4721. Note that we write type TEXT is limited private, but we still introduce the
  4722. private part of the package simply with the word private.
  4723.  
  4724. The two new subprograms are as easy to write as the others:
  4725. 1HPlease type a space to go on, or B to go back.                                      2322 393B391$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             function "="(LEFT, RIGHT : in TEXT) return BOOLEAN is
  4726.              begin
  4727.                 return STR(LEFT) = STR(RIGHT);
  4728.              end "=";
  4729.  
  4730.              procedure SET(TARGET : in out TEXT; TO : in TEXT) is
  4731.              begin
  4732.                 TARGET.LEN := TO.LEN;
  4733.                 TARGET.VAL(1 .. TARGET.LEN) := TO.VAL(1 .. TO.LEN);
  4734.              end SET;
  4735.  
  4736. In summary, we used limited private for type TEXT because Ada's definitions of
  4737. equality and assignment weren't appropriate for that type, and we wanted to
  4738. provide our own definitions.  However, Ada's definitions were appropriate for
  4739. SCREEN_TYPE, so we made that a private type to contain the effects of changes.
  4740. 1HPlease type a space to go on, or B to go back.                                                      262323941395B392$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package STACKS is
  4741.               type STACK is ?
  4742.               procedure PUSH (S : in out STACK; ITEM : in  INTEGER);
  4743.               procedure POP  (S : in out STACK; ITEM : out INTEGER);
  4744.            private
  4745.               type IVECTOR is array(INTEGER range <>) of INTEGER;
  4746.               type STACK is
  4747.                  record
  4748.                     SP : INTEGER range 1 .. 11 := 1;
  4749.                     ST : IVECTOR(1 .. 10);
  4750.                  end record;
  4751.            end STACKS;
  4752.  
  4753. Suppose we want to write a package that lets us create objects of type STACK,
  4754. and push and pop integers on them.  The stacks will be last in, first out.
  4755. (For now, ignore the possibilities of stack underflow and overflow.)  Should
  4756. type STACK be private or limited private?
  4757.  
  4758.                    1.  Type STACK should be private.
  4759.  
  4760.                    2.  Type STACK should be limited private.
  4761. 1HPlease press 1 or 2, or B to go back.                                                     2455 396B393Q393$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package STACKS is
  4762.               type STACK is limited private;
  4763.               procedure PUSH (S : in out STACK; ITEM : in  INTEGER);
  4764.               procedure POP  (S : in out STACK; ITEM : out INTEGER);
  4765.            private
  4766.               type IVECTOR is array(INTEGER range <>) of INTEGER;
  4767.               type STACK is
  4768.                  record
  4769.                     SP : INTEGER range 1 .. 11 := 1;
  4770.                     ST : IVECTOR(1 .. 10);
  4771.                  end record;
  4772.            end STACKS;
  4773.  
  4774. You're right!  Similar to type TEXT, only part of the array in type STACK (the
  4775. part up through SP - 1) is significant; the rest contains garbage.  Thus, Ada's
  4776. test for equality is unsatisfactory for the same reason, and type STACK should
  4777. be limited private.
  4778. 1HPlease type a space to go on, or B or Q to go back to the question.                     2422 396B393Q393$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$           package STACKS is
  4779.               type STACK is ?
  4780.               procedure PUSH (S : in out STACK; ITEM : in  INTEGER);
  4781.               procedure POP  (S : in out STACK; ITEM : out INTEGER);
  4782.            private
  4783.               type IVECTOR is array(INTEGER range <>) of INTEGER;
  4784.               type STACK is
  4785.                  record
  4786.                     SP : INTEGER range 1 .. 11 := 1;
  4787.                     ST : IVECTOR(1 .. 10);
  4788.                  end record;
  4789.            end STACKS;
  4790.  
  4791. No, type STACK is similar to type TEXT in that only part of the array (the part
  4792. up through SP - 1) is significant; the rest contains garbage.  Thus, Ada's test
  4793. for equality is unsatisfactory for the same reason, and type STACK should be
  4794. limited private.
  4795. 1HPlease type a space to go on, or B or Q to go back to the question.                                                      2719 397B393$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                  ACCESS TYPES
  4796.  
  4797. Access types are sometimes called "pointers" in other languages.  However, the
  4798. name "pointer" fell into disrepute, because of "dangling reference" problems.
  4799. With Ada's access types, dangling references are impossible, unless we
  4800. deliberately instantiate UNCHECKED_DEALLOCATION (discussed in the Advanced
  4801. Topics section).
  4802.  
  4803. If we define type DATE as before, and write USA : DATE; then USA has three
  4804. fields, DAY, MONTH, and YEAR.  However, if we write
  4805.  
  4806.                              type P is access DATE;
  4807.                              D1, D2 : P;
  4808.  
  4809. then D1 and D2 are capable of pointing to objects of type DATE.  In most
  4810. implementations of Ada, this means that D1 and D2 can each contain the machine
  4811. address of the start of a record of type DATE.  However, this detail depends on
  4812. the implementation of Ada.  D1 and D2 themselves don't have fields, but the
  4813. objects they can point to have fields.
  4814. 1HPlease type a space to go on, or B to go back.                                                         3160 398B396$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                             type P is access DATE;
  4815.                              D1, D2 : P;
  4816.  
  4817. At present D1 and D2 point to nothing.  However, if we execute
  4818.  
  4819.                                 D1 := new DATE;
  4820.  
  4821. then, at run time, enough memory for one record of type DATE is allocated, and
  4822. D1 is made to point to it.  This new object of type DATE doesn't have a name;
  4823. only the pointer, D1, has a name.  By contrast, when we elaborate USA : DATE;
  4824. we create an object that has a name (USA), but nothing can point to it.
  4825.  
  4826. We can refer to the fields of the nameless object pointed to by D1 as if D1
  4827. itself had fields.  Thus, we can write D1.DAY, D1.MONTH, and D1.YEAR, and use
  4828. these on either side of an assignment: D1.DAY := 12;.  The entire object
  4829. pointed to by D1 is D1.all, so we could write D1.all := (12, OCT, 1492);.  Note
  4830. that D1.DAY is simply an abbreviation for D1.all.DAY.
  4831.  
  4832. We can execute D2 := new DATE'(4, JUL, 1776); giving the new object a value
  4833. when it's created.  We can also declare D3 : P := new DATE; to make D3 point to
  4834. an object when D3 is created, or even write D3 : P := new DATE'(4, JUL, 1776);
  4835. to make D3 point to an object and also give the object a value.
  4836. 1HPlease type a space to go on, or B to go back.                3419 399B397$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We can write D3 := null; to make D3 point nowhere.  When a pointer is declared
  4837. and no initialization is shown, it's automatically initialized to null, so
  4838. D4 : P; means D4 : P := null;.  When a pointer is null, trying to reference the
  4839. object pointed to (D4.DAY or D4.all, etc.) will raise a CONSTRAINT_ERROR.  We
  4840. can test to see if a pointer is null: if D4 = null then ...
  4841.  
  4842. Copying a pointer isn't the same as copying the object pointed to.  If we
  4843. execute D1.all := (12, OCT, 1492); and then D2.all := D1.all;, the entire
  4844. record is copied.  If we change D1.DAY with D1.DAY := 13;, D2.DAY is still 12.
  4845.  
  4846. However, is we execute D1.all := (12, OCT, 1492); and then D2 := D1;, then the
  4847. address in D1 is copied to D2, so that D2 now points to the same place as D1.
  4848. Thus, if we change D1.DAY with D1.DAY := 13;, then D2.DAY is also 13, because
  4849. it references the same memory location.
  4850.  
  4851. If we have D1 := new DATE'(12, OCT, 1492); and D2 := new DATE'(4, JUL, 1776);
  4852. and then execute D2 := D1;, D2 now points where D1 points, and nothing any
  4853. longer points to the object containing (4, JUL, 1776).  Most systems will later
  4854. reclaim the memory occupied by that object, if the memory is needed.  This
  4855. process is called garbage collection.  It's automatic, and normally need not
  4856. concern the programmer.
  4857. 1HPlease type a space to go on, or B to go back.                                                         2971 400B398$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A simple linked list can be thought of as a chain.  Each link contains some
  4858. useful data (perhaps an integer, perhaps pages of information), and a pointer
  4859. to the next item in the chain.  There's also a pointer, usually called HEAD,
  4860. that points to the first link in the chain.  The last link points nowhere.
  4861.  
  4862. A linked list of integers might look something like this:
  4863.          ____       __________          __________          __________
  4864.         |  --|---->| INT   10 |   ,--->| INT   27 |   ,--->| INT   34 |
  4865.         |____|     | NEXT  ---|---'    | NEXT  ---|---'    | NEXT null|
  4866.          HEAD      |__________|        |__________|        |__________|
  4867.  
  4868. To add another integer to the chain, keeping the integers in ascending order,
  4869. we simply break the chain at the appropriate point and insert another link.
  4870.  
  4871. To set up our linked list, we'd like to write type P is access LINK; and write
  4872.  
  4873.                              type LINK is
  4874.                                 record
  4875.                                    INT  : INTEGER;
  4876.                                    NEXT : P;
  4877.                                 end record;
  4878. 1HPlease type a space to go on, or B to go back.     2716 401B399$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$However, the declaration of type P involves LINK, and the declaration of type
  4879. LINK involves P, so neither declaration can come first!  Ada provides a special
  4880. means of solving this problem.  We can write
  4881.  
  4882.                              type LINK;
  4883.                              type P is access LINK;
  4884.                              type LINK is
  4885.                                 record
  4886.                                    INT  : INTEGER;
  4887.                                    NEXT : P;
  4888.                                 end record;
  4889.  
  4890. The first line is called an incomplete type declaration.  It simply tells the
  4891. compiler that type LINK exists.  That's all the information the compiler needs
  4892. to compile the second line.  The second line tells the compiler that objects of
  4893. type P will contain pointers, but for this line the compiler doesn't need to
  4894. know details of the objects pointed to.  The second line must be followed by
  4895. the full definition of type LINK.
  4896. 1HPlease type a space to go on, or B to go back.                                                            2222240214033403B400$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    type PERSON is
  4897.                        record
  4898.                           NAME : STRING(1 .. 10);
  4899.                           AGE  : NATURAL;
  4900.                        end record;
  4901.                     type P is access PERSON;
  4902.                     P1 : P := new PERSON'("Susan     ", 21);
  4903.                     P2 : P := new PERSON'("John      ", 35);
  4904.                     ...
  4905.                     P2 := P1;
  4906.                     P1.AGE := 22;
  4907.  
  4908.  
  4909.                                What is P2.AGE?
  4910.  
  4911.                                1.  P2.AGE is 21.
  4912.  
  4913.                                2.  P2.AGE is 22.
  4914.  
  4915.                                3.  P2.AGE is 35.
  4916. 1HPlease press 1, 2, or 3, or B to go back.                                                      2143 404B401Q401$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    type PERSON is
  4917.                        record
  4918.                           NAME : STRING(1 .. 10);
  4919.                           AGE  : NATURAL;
  4920.                        end record;
  4921.                     type P is access PERSON;
  4922.                     P1 : P := new PERSON'("Susan     ", 21);
  4923.                     P2 : P := new PERSON'("John      ", 35);
  4924.                     ...
  4925.                     P2 := P1;
  4926.                     P1.AGE := 22;
  4927.  
  4928.  
  4929. You're right!  The last line changed P1.AGE to 22.  Since the previous line
  4930. made P2 point where P1 points, P2.AGE is also 22.
  4931. 1HPlease type a space to go on, or B or Q to go back to the question.                                 2125 404B401Q401$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    type PERSON is
  4932.                        record
  4933.                           NAME : STRING(1 .. 10);
  4934.                           AGE  : NATURAL;
  4935.                        end record;
  4936.                     type P is access PERSON;
  4937.                     P1 : P := new PERSON'("Susan     ", 21);
  4938.                     P2 : P := new PERSON'("John      ", 35);
  4939.                     ...
  4940.                     P2 := P1;
  4941.                     P1.AGE := 22;
  4942.  
  4943.  
  4944. No, the last line changed P1.AGE to 22.  Since the previous line made P2 point
  4945. where P1 points, P2.AGE is also 22.
  4946. 1HPlease type a space to go on, or B or Q to go back to the question.                                                   3116 405B401$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Let's use an access type to write a program that gets integers in random order
  4947. from the terminal, maintaining a linked list of them.  When 0 is input, the
  4948. program outputs the integers in ascending order.  This program will be a good
  4949. stepping-stone to Outside Assignment 5.  To simplify inserting an integer into
  4950. the linked list, HEAD will point to an unused LINK, which will in turn point to
  4951. the first actual link in the chain:
  4952.  
  4953.  ____      __________         __________         __________         __________
  4954. |  --|--->| INT      |   ,-->| INT   10 |   ,-->| INT   27 |   ,-->| INT   34 |
  4955. |____|    | NEXT  ---|---'   | NEXT  ---|---'   | NEXT  ---|---'   | NEXT null|
  4956.  HEAD     |__________|       |__________|       |__________|       |__________|
  4957.  
  4958. We could create our linked list using arrays rather than an access type.
  4959. However, we'd have to specify the size of the arrays, placing a limit on the
  4960. number of integers the program can handle.  With the access type, the only
  4961. limit is the amount of available memory.  We'll be able to move our program to
  4962. a larger machine to increase this limit, without changing any code - not even
  4963. one line to specify the size of an array.
  4964.  
  4965. Here's our program ...
  4966. 1HPlease type a space to go on, or B to go back.                                                            2373 406B404$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  4967.         procedure LL_DEMO is
  4968.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  4969.            type LINK;
  4970.            type P is access LINK;
  4971.            type LINK is
  4972.               record
  4973.                  INT  : INTEGER;
  4974.                  NEXT : P;
  4975.               end record;
  4976.            HEAD : P := new LINK;
  4977.            I    : INTEGER;
  4978.            procedure ADD_I_TO_LINKED_LIST is separate;
  4979.            procedure DISPLAY_LINKED_LIST is separate;
  4980.         begin
  4981.            PUT("Type an integer: ");  GET(I);
  4982.            while I /= 0 loop
  4983.               ADD_I_TO_LINKED_LIST;
  4984.               PUT("Type an integer: ");  GET(I);
  4985.            end loop;
  4986.            DISPLAY_LINKED_LIST;
  4987.         end LL_DEMO;
  4988. 1HPlease type a space to go on, or B to go back.   2756 407B405$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ separate (LL_DEMO)
  4989.  procedure DISPLAY_LINKED_LIST is
  4990.     TMP : P := HEAD.NEXT;          -- Skip unused link at the head of the list.
  4991.  begin
  4992.     while TMP /= null loop
  4993.        PUT(TMP.INT);  NEW_LINE;           -- Print integer in the current link.
  4994.        TMP := TMP.NEXT;                         -- Go to next link in the list.
  4995.     end loop;
  4996.  end DISPLAY_LINKED_LIST;
  4997.  
  4998.  separate (LL_DEMO)
  4999.  procedure ADD_I_TO_LINKED_LIST is
  5000.     TMP : P := HEAD;       -- Begin search of where to insert at start of list.
  5001.  begin
  5002.     while TMP /= null and then TMP.NEXT /= null and then TMP.NEXT.INT < I loop
  5003.        TMP := TMP.NEXT;  -- Note use of "and then" to avoid trying to reference
  5004.     end loop;            -- the object pointed to when the pointer is null.
  5005.     TMP.NEXT := new LINK'(I, TMP.NEXT);  -- Create new link and insert in list.
  5006.  end ADD_I_TO_LINKED_LIST;
  5007.  
  5008. The best way to follow these two subprograms is to draw a linked list on a
  5009. piece of scrap paper and "hand execute" the subprograms.
  5010. 1HPlease type a space to go on, or B to go back.                    194744081409241034115412B406$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5011.                    type P is access LINK;
  5012.                    type LINK is
  5013.                       record
  5014.                          F : FLOAT;  -- 2
  5015.                          S : STRING(1 .. 10);  -- 3
  5016.                          A : array(1 .. 10) of INTEGER;  -- 4
  5017.                       end record;
  5018.                    L1 : LINK;  -- 5
  5019.                    P1 : P;
  5020.  
  5021. Which commented line in the above is illegal?
  5022. 1HPlease press 1, 2, 3, 4, or 5, or B to go back.                             2350 413B407Q407$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5023.                    type P is access LINK;
  5024.                    type LINK is
  5025.                       record
  5026.                          F : FLOAT;  -- 2
  5027.                          S : STRING(1 .. 10);  -- 3
  5028.                          A : array(1 .. 10) of INTEGER;  -- 4
  5029.                       end record;
  5030.                    L1 : LINK;  -- 5
  5031.                    P1 : P;
  5032.  
  5033.  
  5034. You're right!  Inside a record definition, the name of a field must be
  5035. followed by a type name, not array.  We would first have to say something like
  5036. type LINE is array(INTEGER range <>) of INTEGER;, and then change the field
  5037. definition to
  5038.  
  5039.                          A : LINE(1 .. 10);
  5040. 1HPlease type a space to go on, or B or Q to go back to the question.                          2121 413B407Q407$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5041.                    type P is access LINK;
  5042.                    type LINK is
  5043.                       record
  5044.                          F : FLOAT;  -- 2
  5045.                          S : STRING(1 .. 10);  -- 3
  5046.                          A : array(1 .. 10) of INTEGER;  -- 4
  5047.                       end record;
  5048.                    L1 : LINK;  -- 5
  5049.                    P1 : P;
  5050.  
  5051.  
  5052. No, the first line is legal.  Ada allows an incomplete type declaration to
  5053. precede the declaration of an access type, provided the complete type
  5054. declaration follows.
  5055. 1HPlease type a space to go on, or B or Q to go back to the question.                                                       2034 413B407Q407$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5056.                    type P is access LINK;
  5057.                    type LINK is
  5058.                       record
  5059.                          F : FLOAT;  -- 2
  5060.                          S : STRING(1 .. 10);  -- 3
  5061.                          A : array(1 .. 10) of INTEGER;  -- 4
  5062.                       end record;
  5063.                    L1 : LINK;  -- 5
  5064.                    P1 : P;
  5065.  
  5066.  
  5067. No, the declaration of F inside the record definition is legal, because Ada
  5068. records may contain fields of any type.
  5069. 1HPlease type a space to go on, or B or Q to go back to the question.                                          2034 413B407Q407$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5070.                    type P is access LINK;
  5071.                    type LINK is
  5072.                       record
  5073.                          F : FLOAT;  -- 2
  5074.                          S : STRING(1 .. 10);  -- 3
  5075.                          A : array(1 .. 10) of INTEGER;  -- 4
  5076.                       end record;
  5077.                    L1 : LINK;  -- 5
  5078.                    P1 : P;
  5079.  
  5080.  
  5081. No, the declaration of S inside the record definition is legal, because Ada
  5082. records may contain fields of any type.
  5083. 1HPlease type a space to go on, or B or Q to go back to the question.                                          2260 413B407Q407$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   type LINK;  -- 1
  5084.                    type P is access LINK;
  5085.                    type LINK is
  5086.                       record
  5087.                          F : FLOAT;  -- 2
  5088.                          S : STRING(1 .. 10);  -- 3
  5089.                          A : array(1 .. 10) of INTEGER;  -- 4
  5090.                       end record;
  5091.                    L1 : LINK;  -- 5
  5092.                    P1 : P;
  5093.  
  5094.  
  5095. No, the declaration of L1 as type LINK is legal.  Even though type P was
  5096. declared to be access LINK and we ordinarily would declare objects to be of
  5097. type P, we may also directly declare objects to be of type LINK.  Of course,
  5098. nothing can point to such objects.
  5099. 1HPlease type a space to go on, or B or Q to go back to the question.                3172 414B407$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       USER DEFINED TYPES AND PORTABILITY
  5100.  
  5101. In some implementations of Ada, INTEGERs are represented by 32-bit two's
  5102. complement numbers, giving the range -2_147_483_648 .. 2_147_483_648.  Other
  5103. implementations use 16-bit two's complement INTEGERs, giving the range
  5104. -32768 .. 32767.  However, some of the 16-bit implementations also provide a
  5105. 32-bit type called LONG_INTEGER.
  5106.  
  5107. Suppose we need a variable called NUMBER to count from zero to one million.  We
  5108. could declare NUMBER: INTEGER; for the 32-bit implementation, and change this
  5109. to NUMBER : LONG_INTEGER; when we port the program to a machine running a
  5110. 16-bit version that provides LONG_INTEGER.  However, we could also declare
  5111.  
  5112.                      type COUNTER is range 0 .. 1_000_000;
  5113.                      NUMBER : COUNTER;
  5114.  
  5115. and both implementations of Ada will automatically select the appropriate
  5116. internal representation for our type COUNTER!  The 32-bit Ada will select
  5117. INTEGER, and the 16-bit Ada will select LONG_INTEGER.  This gives us the
  5118. advantage that no code has to be changed when the program is ported.  COUNTER
  5119. is called a user-defined type.  Of course, we must use explicit type
  5120. conversion to mix objects of type COUNTER with objects of other types.
  5121. 1HPlease type a space to go on, or B to go back.    2657 415B413$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Similarly, different implementations of Ada provide different representations
  5122. for type FLOAT, and some provide a type LONG_FLOAT.  We can declare
  5123.  
  5124.                              type REAL is digits 8;
  5125.                              F : REAL;
  5126.  
  5127. and be certain that F will have at least 8 digits of accuracy on any machine
  5128. that accepts this type declaration.  A range constraint is optional.
  5129.  
  5130. User defined types also apply to fixed point numbers; these will be discussed
  5131. in the Advanced Topics section.
  5132.  
  5133. It's possible to make a declaration that will be accepted by only some
  5134. implementations of Ada.  For example, if we declare
  5135.  
  5136.                     type X is digits 30 range 0.0 .. 100.0;
  5137.  
  5138. some implementations of Ada might have to report that there's no available type
  5139. that gives at least 30 digits of accuracy.
  5140.  
  5141. No language can give perfectly portable programs, but Ada truly advanced the
  5142. state of the art in portability.
  5143. 1HPlease type a space to go on, or B to go back.                   2839 416B414$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                 DERIVED TYPES
  5144.  
  5145. Derived types are created to prevent accidental mixing of objects.  Unlike
  5146. subtypes, derived types are separate types.  For example,
  5147.  
  5148.                type NO_OF_APPLES  is new INTEGER;
  5149.                type NO_OF_ORANGES is new INTEGER range 0 .. 100;
  5150.                NOA : NO_OF_APPLES;
  5151.                NOO : NO_OF_ORANGES;
  5152.                I   : INTEGER;
  5153.                ...
  5154.                NOA := NOA + NOO;  -- Illegal
  5155.                NOA := NOA + NOA;
  5156.                NOA := NOA + I;  -- Illegal
  5157.                NOA := NOA + NO_OF_APPLES(I);
  5158.                NOA := NOA + NO_OF_APPLES(NOO);
  5159.  
  5160. A derived type is denoted by the reserved word new followed by an existing type
  5161. like INTEGER.  The operations that Ada knows for INTEGERs, such as addition,
  5162. are "inherited" by the derived types so that, for example, Ada knows how to add
  5163. two objects of type NO_OF_ORANGES.  As the examples above show, we can't mix
  5164. types accidentally, but we can deliberately mix them by converting first.
  5165. 1HPlease type a space to go on, or B to go back.                                     2073 417B415$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In summary,
  5166.  
  5167.  
  5168.            Subtypes are usually created to provide range constraints:
  5169.  
  5170.                  subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
  5171.  
  5172.  
  5173.         Derived types are usually created to prevent accidental mixing:
  5174.  
  5175.                     type NO_OF_APPLES  is new INTEGER;
  5176.                     type NO_OF_ORANGES is new INTEGER ... ;
  5177.  
  5178.  
  5179.           User-defined types are usually created to gain portability:
  5180.  
  5181.                      type COUNTER is range 0 .. 1_000_000;
  5182.                      type REAL    is digits 8;
  5183. 1HPlease type a space to go on, or B to go back.   2325141824193420B416$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ type METERS            is new FLOAT;
  5184.  type SECONDS           is new FLOAT;
  5185.  type METERS_PER_SECOND is new FLOAT;
  5186.  ...
  5187.  function "*"(LEFT : in METERS_PER_SECOND; RIGHT : in SECONDS) return METERS is
  5188.  begin
  5189.     return METERS(LEFT) * METERS(RIGHT);
  5190.  end "*";
  5191.  function "*"(LEFT : in SECONDS; RIGHT : in METERS_PER_SECOND) return METERS is
  5192.  begin
  5193.     return RIGHT * LEFT;
  5194.  end "*";
  5195.  function "/"(LEFT : in METERS; RIGHT : in SECONDS) return METERS_PER_SECOND is
  5196.  begin
  5197.     return METERS_PER_SECOND(LEFT) / METERS_PER_SECOND(RIGHT);
  5198.  end "/";
  5199.  
  5200.                  The above program segment is an example of ...
  5201.                  1.  derived types.
  5202.                  2.  user-defined types.
  5203.                  3.  subtypes.
  5204. 1HPlease press 1, 2, or 3, or B to go back.                                                   1626 421B417Q417$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ type METERS            is new FLOAT;
  5205.  type SECONDS           is new FLOAT;
  5206.  type METERS_PER_SECOND is new FLOAT;
  5207.  
  5208.  
  5209. You're right!  The reserved word new in the segment above tells us that we're
  5210. defining derived types.
  5211. 1HPlease type a space to go on, or B or Q to go back to the question.                                                  1637 421B417Q417$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ type METERS            is new FLOAT;
  5212.  type SECONDS           is new FLOAT;
  5213.  type METERS_PER_SECOND is new FLOAT;
  5214.  
  5215.  
  5216. No, examples of user-defined types are
  5217.  
  5218.                      type COUNTER is range 0 .. 1_000_000;
  5219.                      type REAL    is digits 8;
  5220. 1HPlease type a space to go on, or B or Q to go back to the question.                                       1515 421B417Q417$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ type METERS            is new FLOAT;
  5221.  type SECONDS           is new FLOAT;
  5222.  type METERS_PER_SECOND is new FLOAT;
  5223.  
  5224.  
  5225. No, subtypes are usually created to provide range constraints.
  5226. 1HPlease type a space to go on, or B or Q to go back to the question.                                                             2744 422B417$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   EXCEPTIONS
  5227.  
  5228. When an error occurs during the elaboration or execution of a statement, Ada is
  5229. said to raise an exception.  Ordinarily this stops the program, but Ada
  5230. programs can trap exceptions and execute a special block of code when one
  5231. occurs.  This code is called an exception handler.
  5232.  
  5233. We can define our own exceptions, but five of them are predefined by Ada:
  5234.  
  5235. CONSTRAINT_ERROR
  5236.      This is the exception encountered most often by beginners, because it can
  5237. be caused by a number of different things.  It can be raised by a subscript out
  5238. of range, a subtype out of range (USA.DAY := 32;), an attribute used improperly
  5239. (INTEGER'VALUE("12X3") or MONTH_TYPE'VAL(13)), assigning an array of one length
  5240. to a destination of another (H : STRING(1 .. 5) := "Hi";), or by attempting to
  5241. access an object with a null pointer.
  5242.  
  5243. NUMERIC_ERROR
  5244.      This can be raised by an arithmetic overflow, or by an attempt to divide
  5245. by zero.
  5246. 1HPlease type a space to go on, or B to go back.                                2931 423B421$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$PROGRAM_ERROR
  5247.      This is rarely encountered by beginners, but it can be raised by skipping
  5248. around the return statement in a function and running into the end statement.
  5249.  
  5250. STORAGE_ERROR
  5251.      This is raised by running out of memory, as with a recursive program
  5252. calling itself unconditionally or an attempt to create an infinitely large
  5253. linked list.
  5254.  
  5255. TASKING_ERROR
  5256.      This will be discussed in the section on Tasking.
  5257.  
  5258. An exception handler is introduced by the reserved word exception; its
  5259. structure is similar to that of a case construct.  We'll see an example in a
  5260. moment.  Unlike a case construct, an exception handler need not account for all
  5261. the possibilities.
  5262.  
  5263. An exception handler can be placed in a subprogram, in the initialization code
  5264. of a package, in a task (to be discussed in the section on Tasking), or in a
  5265. block (to be discussed later in this section).  Here's a procedure with an
  5266. exception handler that handles an exception, WRONG, that we declare ourselves,
  5267. as well as the built-in exception NUMERIC_ERROR:
  5268. 1HPlease type a space to go on, or B to go back.                                             2417 424B422$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        with TEXT_IO; use TEXT_IO;
  5269.         procedure EXCEPTION_DEMO is
  5270.            package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  5271.            I     : INTEGER;
  5272.            WRONG : exception;
  5273.         begin
  5274.            loop
  5275.               NEW_LINE(2);  PUT("Type a positive integer. ");  GET(I);
  5276.               if I <= 0 then
  5277.                  raise WRONG;
  5278.               end if;
  5279.               PUT("The square is ... ");
  5280.               PUT(I*I);  -- Will raise NUMERIC_ERROR if I is too large.
  5281.            end loop;
  5282.         exception
  5283.            when NUMERIC_ERROR =>
  5284.               PUT(" ... too big.");
  5285.            when WRONG =>
  5286.               NEW_LINE;
  5287.               PUT("I said POSITIVE integer!");
  5288.         end EXCEPTION_DEMO;
  5289. 1HPlease type a space to go on, or B to go back.                                                           3719 425B423$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We can deliberately raise an exception (either user-defined or built-in) with
  5290. the raise statement, as in raise WRONG; or raise CONSTRAINT_ERROR;.  Also,
  5291. ordinary statements can raise exceptions.  In our sample program, PUT(I*I);
  5292. raises NUMERIC_ERROR if I is too large.  When an executable statement raises an
  5293. exception, the exception handler is executed instead of the rest of the
  5294. procedure, function, etc.  Our program keeps asking for integers and printing
  5295. their squares until an exception is raised.  Then, the exception handler is
  5296. executed, and there's no way to get back into the procedure to ask for another
  5297. integer (short of a recursive call).  Even a goto from the exception handler to
  5298. the main part of the procedure is forbidden.  Very soon we'll show how the
  5299. block construct can overcome this problem, so that our program will continue to
  5300. ask for more integers even after an exception is handled.
  5301.  
  5302. As with case constructs, an exception handler may use the vertical bar to
  5303. denote multiple choices (when STORAGE_ERROR | NUMERIC_ERROR => block of code),
  5304. and it may say when others => to handle all cases not covered earlier.  But
  5305. there's no way to test, inside the exception handler, which line raised the
  5306. exception.  We can only test which kind of exception was raised.
  5307.  
  5308. Don't use exceptions where a simple if will do.  In our program, trapping the
  5309. arithmetic overflow was OK, but the if could have handled I <= 0 without
  5310. raising WRONG.  This exception was declared only to give a simple example.
  5311. 1HPlease type a space to go on, or B to go back.                                                         183614262427342844295430B424$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5312.  
  5313.                               2.  NUMERIC_ERROR
  5314.  
  5315.                               3.  PROGRAM_ERROR
  5316.  
  5317.                               4.  STORAGE_ERROR
  5318.  
  5319.                               5.  TASKING_ERROR
  5320.  
  5321.  
  5322. Assuming RAINBOW_COLOR and TRAFFIC_LIGHT_COLOR are defined as before, which of
  5323. the above exceptions would be raised by RAINBOW_COLOR'VALUE("AMBER")?
  5324. 1HPlease press 1, 2, 3, 4, or 5, or B to go back.                                        1764 431B425Q425$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5325.  
  5326.                               2.  NUMERIC_ERROR
  5327.  
  5328.                               3.  PROGRAM_ERROR
  5329.  
  5330.                               4.  STORAGE_ERROR
  5331.  
  5332.                               5.  TASKING_ERROR
  5333.  
  5334.  
  5335. You're right!  Using an attribute improperly in this way will raise
  5336. CONSTRAINT_ERROR.
  5337. 1HPlease type a space to go on, or B or Q to go back to the question.            1755 431B425Q425$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5338.  
  5339.                               2.  NUMERIC_ERROR
  5340.  
  5341.                               3.  PROGRAM_ERROR
  5342.  
  5343.                               4.  STORAGE_ERROR
  5344.  
  5345.                               5.  TASKING_ERROR
  5346.  
  5347.  
  5348. No, NUMERIC_ERROR is usually raised by arithmetic overflow, or attempted
  5349. division by zero.
  5350. 1HPlease type a space to go on, or B or Q to go back to the question.                     1762 431B425Q425$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5351.  
  5352.                               2.  NUMERIC_ERROR
  5353.  
  5354.                               3.  PROGRAM_ERROR
  5355.  
  5356.                               4.  STORAGE_ERROR
  5357.  
  5358.                               5.  TASKING_ERROR
  5359.  
  5360.  
  5361. No, PROGRAM_ERROR is usually raised by skipping around the return statement in
  5362. a function.
  5363. 1HPlease type a space to go on, or B or Q to go back to the question.              1717 431B425Q425$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5364.  
  5365.                               2.  NUMERIC_ERROR
  5366.  
  5367.                               3.  PROGRAM_ERROR
  5368.  
  5369.                               4.  STORAGE_ERROR
  5370.  
  5371.                               5.  TASKING_ERROR
  5372.  
  5373.  
  5374. No, STORAGE_ERROR is raised by running out of memory.
  5375. 1HPlease type a space to go on, or B or Q to go back to the question.                                                           1756 431B425Q425$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                              1.  CONSTRAINT_ERROR
  5376.  
  5377.                               2.  NUMERIC_ERROR
  5378.  
  5379.                               3.  PROGRAM_ERROR
  5380.  
  5381.                               4.  STORAGE_ERROR
  5382.  
  5383.                               5.  TASKING_ERROR
  5384.  
  5385.  
  5386. No, TASKING_ERROR is raised only by programs using tasking, which we haven't
  5387. yet discussed.
  5388. 1HPlease type a space to go on, or B or Q to go back to the question.                    2914 432B425$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A block construct lets us declare objects in the executable region of the
  5389. program.  For example, in the following, I and F come into existence where
  5390. they're declared, and go out of existence at the following end statement:
  5391.  
  5392.                             procedure BLOCK_DEMO is
  5393.                                Q : FLOAT;
  5394.                             begin
  5395.                                Q := 0.0;
  5396.                                declare
  5397.                                   I : INTEGER;
  5398.                                   F : FLOAT;
  5399.                                begin
  5400.                                   I := 5;
  5401.                                   F := Q;
  5402.                                end;
  5403.                                Q := Q + 3.0;
  5404.                             end BLOCK_DEMO;
  5405.  
  5406. However, the usual use of a block is to localize an exception handler, not to
  5407. bring objects into existence in the executable region of a program.  The
  5408. declarative part of the block is optional.  For example, let's rewrite
  5409. EXCEPTION_DEMO to make use of a block with an exception handler.
  5410. 1HPlease type a space to go on, or B to go back.                                                              2372 433B431$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       with TEXT_IO; use TEXT_IO;
  5411.        procedure EXCEPTION_DEMO is
  5412.           package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  5413.           I     : INTEGER;
  5414.           WRONG : exception;
  5415.        begin
  5416.           loop
  5417.              begin
  5418.                 NEW_LINE(2);  PUT("Type a positive integer. ");  GET(I);
  5419.                 if I <= 0 then
  5420.                    raise WRONG;
  5421.                 end if;
  5422.                 PUT("The square is ... ");
  5423.                 PUT(I*I);
  5424.              exception
  5425.                 when NUMERIC_ERROR =>
  5426.                    PUT(" ... too big.");
  5427.                 when WRONG =>
  5428.                    NEW_LINE;  PUT("I said POSITIVE integer!");
  5429.              end;
  5430.           end loop;
  5431.        end EXCEPTION_DEMO;
  5432. 1HPlease type a space to go on, or B to go back.    3532 434B432$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that in our rewritten program, a block with an exception handler has been
  5433. created inside the loop.  Now, if an exception occurs, the handler will be
  5434. executed instead of the rest of the block, not the rest of the procedure.
  5435. Thus, the loop will still be executed, and the program will continue to ask
  5436. for integers after an exception is handled.
  5437.  
  5438. There are two advantages to confining exception handlers to small blocks.
  5439. First, we narrow down the range of statements that might have raised the
  5440. exception.  Recall that the handler can't test which line raised the exception,
  5441. but it must have been one of the lines in the block.  (If an exception is
  5442. raised outside the block, our program provides no handler for it.)  Second,
  5443. program execution will continue after the end of the block.
  5444.  
  5445. If an exception occurs for which there's no handler, the exception reaches the
  5446. next higher level.  For example, if the block in EXCEPTION_DEMO somehow raises
  5447. STORAGE_ERROR and doesn't handle it, an exception handler for the whole
  5448. procedure would get a chance to handle it.  (In our case, there is none.)  If
  5449. it's still unhandled, it's as if the call to EXCEPTION_DEMO raised
  5450. STORAGE_ERROR.  If the caller doesn't handle it, the exception reaches the
  5451. caller's caller, etc.  If the exception reaches the main program and is still
  5452. unhandled, the program is stopped and the system prints the name of the
  5453. exception.  However, exceptions that are handled don't reach the caller.
  5454. 1HPlease type a space to go on, or B to go back.                                            3134 435B433$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In the unusual case of an exception raised in the declarative region, the unit
  5455. raising the exception (subprogram, block, etc.) is not given a chance to handle
  5456. it.  Exceptions raised in the declarative region immediately reach the next
  5457. higher level.
  5458.  
  5459. In a handler, the word raise may be used without a name of an exception to
  5460. re-raise whatever exception brought control to the handler.  This is especially
  5461. useful after when others =>, because any one of a number of exceptions might
  5462. have transferred control there.  For example,
  5463.  
  5464.                  when others =>
  5465.                     PUT_LINE("I don't know what went wrong.");
  5466.                     -- Close files and do general cleanup.
  5467.                     raise;
  5468.  
  5469. This lets us do some processing of the error, and still lets the next higher
  5470. level do additional processing.  Note that it's superfluous to say simply when
  5471. others => raise; because the exception will reach the next higher level even if
  5472. that code is omitted.  Any unhandled exception reaches the next higher level.
  5473.  
  5474. An error occurring in an exception handler is unhandled and reaches the next
  5475. higher level (unless it occurs in a block with its own exception handler).
  5476. 1HPlease type a space to go on, or B to go back.                                          234524361437B434$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          with TEXT_IO; use TEXT_IO;             separate (ONE)
  5477.           procedure ONE is                       procedure TWO is
  5478.              procedure TWO is separate;             CAIN : exception;
  5479.           begin                                  begin
  5480.              TWO;                                   raise CAIN;
  5481.           exception                              exception
  5482.              when others =>                         when others =>
  5483.                 PUT_LINE("1");                         PUT_LINE("2");
  5484.           end ONE;                               end TWO;
  5485.  
  5486.  
  5487.                        What will the above program print?
  5488.  
  5489.                        1.  The program will print 1.
  5490.  
  5491.                        2.  The program will print 2.
  5492. 1HPlease press 1 or 2, or B to go back.                               2264 438B435Q435$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          with TEXT_IO; use TEXT_IO;             separate (ONE)
  5493.           procedure ONE is                       procedure TWO is
  5494.              procedure TWO is separate;             CAIN : exception;
  5495.           begin                                  begin
  5496.              TWO;                                   raise CAIN;
  5497.           exception                              exception
  5498.              when others =>                         when others =>
  5499.                 PUT_LINE("1");                         PUT_LINE("2");
  5500.           end ONE;                               end TWO;
  5501.  
  5502.  
  5503. You're right!  TWO handles the exception, so it never reaches ONE.
  5504. 1HPlease type a space to go on, or B or Q to go back to the question.            2225 438B435Q435$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$          with TEXT_IO; use TEXT_IO;             separate (ONE)
  5505.           procedure ONE is                       procedure TWO is
  5506.              procedure TWO is separate;             CAIN : exception;
  5507.           begin                                  begin
  5508.              TWO;                                   raise CAIN;
  5509.           exception                              exception
  5510.              when others =>                         when others =>
  5511.                 PUT_LINE("1");                         PUT_LINE("2");
  5512.           end ONE;                               end TWO;
  5513.  
  5514.  
  5515. No, TWO handles the exception, so it never reaches ONE.
  5516. 1HPlease type a space to go on, or B or Q to go back to the question.                                                   3125 439B435$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                               MORE ABOUT TEXT_IO
  5517.  
  5518. We're almost ready for Outside Assignment 5.  For that assignment, we had to
  5519. cover type TEXT, access types, and exceptions.  We also need to learn a little
  5520. more about TEXT_IO before we do the assignment.
  5521.  
  5522. TEXT_IO is used for input and output to and from text files as well as input
  5523. and output to and from the terminal.  Text files are files that can be listed
  5524. at the terminal.  (Binary files and random access files are handled with the
  5525. packages SEQUENTIAL_IO and DIRECT_IO, which will be discussed in the Advanced
  5526. Topics section.)
  5527.  
  5528. The full specification of TEXT_IO appears in section 14.3.10 of the LRM.  It's
  5529. rather long, and some of the procedures and functions are rarely used.  So
  5530. there's a simplified specification of TEXT_IO in your printed course notes,
  5531. starting on page 16.  Please consult your printed course notes during the
  5532. following discussion.
  5533.  
  5534. Note that there's a limited private type called FILE_TYPE.  For each file that
  5535. our program will use, we must create an object of this type, for example,
  5536. F1, F2 : FILE_TYPE;.  We can then use these objects in the procedures CREATE
  5537. and OPEN, to associate file names with the objects of type FILE_TYPE.
  5538. 1HPlease type a space to go on, or B to go back.                                                   3426 440B438$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Note that the I/O procedures, such as NEW_LINE, PUT, and GET, have one version
  5539. for use with the terminal, and another version for use with a file.  The file
  5540. version takes an object of type FILE_TYPE, not the name of the file.  The file
  5541. must first have been CREATEd or OPENed.
  5542.  
  5543. The exception STATUS_ERROR is raised by trying to do I/O on a closed file.
  5544. MODE_ERROR is raised by trying to read from a file opened or created with mode
  5545. OUT_FILE, or by trying to write to a file of mode IN_FILE.  NAME_ERROR is
  5546. raised by trying to OPEN a file that doesn't exist, or by trying to CREATE a
  5547. file with a name not allowed by the system.  END_ERROR is raised by trying to
  5548. read past an end-of-file.
  5549.  
  5550. NEW_LINE creates one or more blank lines on output, and SKIP_LINE skips one or
  5551. more lines of input.  We can PUT characters and strings, and we can PUT_LINE a
  5552. string.  We can GET a character, and GET_LINE a string.  Note that when we
  5553. GET_LINE a string, the procedure returns the number of characters that were in
  5554. the line.  Thus, if we have S : STRING(1 .. 80);  LEN : INTEGER; and we execute
  5555. GET_LINE(S, LEN); and the user types Hello, LEN will be set to 5, S(1 .. 5)
  5556. will be set to "Hello", and the rest of S will be unmodified.
  5557.  
  5558. The generic package INTEGER_IO can be instantiated for any integer type,
  5559. including user-defined types and derived types like COUNTER and NO_OF_APPLES.
  5560. 1HPlease type a space to go on, or B to go back.                                                  2825 441B439$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$When we call PUT in our instantiation of INTEGER_IO, we can optionally specify
  5561. the width and the base.
  5562.  
  5563. The generic package FLOAT_IO can be instantiated for any floating point type,
  5564. such as FLOAT and the user-defined type REAL that we created earlier.  PUT
  5565. allows us optionally to specify the number of places before and after the
  5566. decimal point, and the size of the optional exponent field.
  5567.  
  5568. The generic package ENUMERATION_IO can be instantiated for any enumeration
  5569. type.  PUT allows us optionally to specify the width.
  5570.  
  5571. TEXT_IO contains another generic package FIXED_IO for fixed point types, not
  5572. shown in our simplified version.  Fixed point types will be discussed in the
  5573. Advanced Topics section.
  5574.  
  5575. To illustrate the use of TEXT_IO, here's a simple program that prompts for the
  5576. names of an old input file and a new output file, and copies the input file to
  5577. the output.  It's assumed that the input file is an ASCII text file no wider
  5578. than 80 characters, and that it contains no special control characters such as
  5579. form feeds:
  5580. 1HPlease type a space to go on, or B to go back.                                                   2555 442B440$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         with TEXT_IO; use TEXT_IO;
  5581.          procedure COPY is
  5582.             F1, F2 : FILE_TYPE;
  5583.             S      : STRING(1 .. 80);
  5584.             LEN    : INTEGER;
  5585.          begin
  5586.             PUT("Input file: ");  GET_LINE(S, LEN);
  5587.             OPEN(FILE => F1, MODE => IN_FILE, NAME => S(1 .. LEN));
  5588.             PUT("Output file: ");  GET_LINE(S, LEN);
  5589.             CREATE(FILE => F2, MODE => OUT_FILE, NAME => S(1 .. LEN));
  5590.             while not END_OF_FILE(F1) loop
  5591.                GET_LINE(F1, S, LEN);
  5592.                PUT_LINE(F2, S(1 .. LEN));
  5593.             end loop;
  5594.             CLOSE(F1);
  5595.             CLOSE(F2);
  5596.          end COPY;
  5597.  
  5598. The statements CLOSE(F1); and CLOSE(F2); aren't really necessary, because all
  5599. files are automatically closed when the main program terminates.
  5600.  
  5601. This program also appears on page 18 of your printed course notes.
  5602. 1HPlease type a space to go on, or B to go back.                     2525 443B441$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$As this is written (March, 1988), there's no way to test whether a file already
  5603. exists without trying to OPEN it and trapping the NAME_ERROR if the file
  5604. doesn't exist.  There's talk of enhancing TEXT_IO with the next revision of the
  5605. Ada standard.
  5606.  
  5607. The following function determines whether a file name represents an existing
  5608. file.  It appears on page 18 of your printed course notes:
  5609.  
  5610.             with TEXT_IO; use TEXT_IO;
  5611.             function EXISTS(FILE_NAME : in STRING) return BOOLEAN is
  5612.                F      : FILE_TYPE;
  5613.                ANSWER : BOOLEAN := TRUE;
  5614.             begin
  5615.                begin
  5616.                   OPEN(F, IN_FILE, S);
  5617.                   CLOSE(F);
  5618.                exception
  5619.                   when NAME_ERROR => ANSWER := FALSE;
  5620.                end;
  5621.                return ANSWER;
  5622.             end EXISTS;
  5623. 1HPlease type a space to go on, or B to go back.                                                   16211444244534464447B442$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                1.  STATUS_ERROR
  5624.  
  5625.                                 2.  MODE_ERROR
  5626.  
  5627.                                 3.  NAME_ERROR
  5628.  
  5629.                                 4.  END_ERROR
  5630.  
  5631.  
  5632.       Which exception is raised by attempting to do I/O on a closed file?
  5633. 1HPlease press 1, 2, 3, or 4, or B to go back.                                                       1664 448B443Q443$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                1.  STATUS_ERROR
  5634.  
  5635.                                 2.  MODE_ERROR
  5636.  
  5637.                                 3.  NAME_ERROR
  5638.  
  5639.                                 4.  END_ERROR
  5640.  
  5641.  
  5642. You're right!  STATUS_ERROR is raised by an attempt to do I/O on a closed file.
  5643. 1HPlease type a space to go on, or B or Q to go back to the question.            1720 448B443Q443$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                1.  STATUS_ERROR
  5644.  
  5645.                                 2.  MODE_ERROR
  5646.  
  5647.                                 3.  NAME_ERROR
  5648.  
  5649.                                 4.  END_ERROR
  5650.  
  5651.  
  5652. No, MODE_ERROR is raised by an attempt to read from a file of mode OUT_FILE, or
  5653. write to a file of mode IN_FILE.
  5654. 1HPlease type a space to go on, or B or Q to go back to the question.                                                        1720 448B443Q443$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                1.  STATUS_ERROR
  5655.  
  5656.                                 2.  MODE_ERROR
  5657.  
  5658.                                 3.  NAME_ERROR
  5659.  
  5660.                                 4.  END_ERROR
  5661.  
  5662.  
  5663. No, NAME_ERROR is raised by an attempt to OPEN a file that doesn't exist, or
  5664. CREATE a file with an illegal name.
  5665. 1HPlease type a space to go on, or B or Q to go back to the question.                                                        1637 448B443Q443$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                1.  STATUS_ERROR
  5666.  
  5667.                                 2.  MODE_ERROR
  5668.  
  5669.                                 3.  NAME_ERROR
  5670.  
  5671.                                 4.  END_ERROR
  5672.  
  5673.  
  5674. No, END_ERROR is raised by an attempt to read past an end-of-file.
  5675. 1HPlease type a space to go on, or B or Q to go back to the question.                                       3440 449B443$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              OUTSIDE ASSIGNMENT 5 - WRITING A SIMPLE LINE EDITOR
  5676.  
  5677. We're finally ready for the next Outside Assignment!  This assignment will give
  5678. you a chance to write a program of greater complexity than the previous
  5679. assignments.  By the time you've completed Outside Assignment 5, you should
  5680. feel comfortable with Ada.  The full set of requirements for the line editor we
  5681. want you to write are in your printed course notes, starting on page 19.  We'll
  5682. discuss them briefly here.  No test driver is supplied, but after you've
  5683. written the program, we'll give you some tests to perform manually on your line
  5684. editor.  You've completed the assignment when your editor passes all the tests.
  5685.  
  5686. Imagine that your screen editor is unavailable to a particular user, perhaps
  5687. because he's dialing your computer from a remote location, and your screen
  5688. editor writes directly to the screen.  You want to write a line editor.  While
  5689. your computer already has a line editor called EDLIN, it's difficult to learn
  5690. to use.  The line editor you'll write, called LEDIT, will take almost no effort
  5691. to learn.  The only commands are LIST and EXIT.
  5692.  
  5693. The user begins each line of text with a line number, similar to Basic.  Line
  5694. numbers must be integers between 1 and 29999.  Regardless of the order in which
  5695. lines are entered, LEDIT maintains a linked list of lines in order by number,
  5696. so that it can LIST the text in order, or write it to a file.
  5697. 1HPlease type a space to go on, or B to go back.                                    1974 450B448$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Line numbers need not be consecutive, and they may be preceded by any number of
  5698. spaces.  For example, if we type
  5699.  
  5700. 40 -- This is a comment.
  5701.    20 begin
  5702. 10 with TEXT_IO; use TEXT_IO;
  5703.       30 end ADD;
  5704.  
  5705. and then type LIST, the editor displays
  5706.  
  5707.    10 with TEXT_IO; use TEXT_IO;
  5708.    20 begin
  5709.    30 end ADD;
  5710.    40 -- This is a comment.
  5711.  
  5712. To insert lines, we merely type lines with intermediate line numbers.  In our
  5713. example, if we now type
  5714.  
  5715. 15 procedure HELLO is
  5716. LIST
  5717.  
  5718. we'll see
  5719. 1HPlease type a space to go on, or B to go back.  1863 451B449$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   10 with TEXT_IO; use TEXT_IO;
  5720.    15 procedure HELLO is
  5721.    20 begin
  5722.    30 end ADD;
  5723.    40 -- This is a comment.
  5724.  
  5725. To replace a line, we simply retype the line with the same line number as the
  5726. line to be replaced, and to delete a line, we type only the line number.  If
  5727. we now type
  5728.  
  5729. 15 procedure ADD is
  5730. 40
  5731. LIST
  5732.  
  5733. we'll see
  5734.  
  5735.    10 with TEXT_IO; use TEXT_IO;
  5736.    15 procedure ADD is
  5737.    20 begin
  5738.    30 end ADD;
  5739. 1HPlease type a space to go on, or B to go back.             2523 452B450$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Thus the user can insert, replace, and delete lines by line numbers, without
  5740. learning any commands!  If the user forgets the space after the line number, no
  5741. harm is done; LEDIT takes 20begin the same as 20 begin.  However, the user can
  5742. indent code by adding extra spaces after the line number.  The following
  5743. example has three extra spaces after each line number (four spaces total):
  5744.  
  5745. 24    PUT(2 + 2);
  5746. 26    NEW_LINE;
  5747. 18    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  5748. LIST
  5749.  
  5750.    10 with TEXT_IO; use TEXT_IO;
  5751.    15 procedure ADD is
  5752.    18    package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
  5753.    20 begin
  5754.    24    PUT(2 + 2);
  5755.    26    NEW_LINE;
  5756.    30 end ADD;
  5757.  
  5758. When LISTing, LEDIT always allows exactly five spaces for the line number, so
  5759. that the text lines up correctly:
  5760. 1HPlease type a space to go on, or B to go back.                                                     2430 453B451$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$LIST
  5761.  
  5762.     2 This is a sample listing,
  5763.    20 showing how the text
  5764.   200 lines up, even when
  5765.  2000 some line numbers are
  5766. 20000 longer than others.
  5767.  
  5768. When we type EXIT, LEDIT writes the output file without the line numbers.  The
  5769. text above would all start in column 1 of the output file.
  5770.  
  5771. For LEDIT to be useful with files larger than a page, it must be possible to
  5772. list a range of lines:
  5773.  
  5774. LIST 20 - 30
  5775.  
  5776. This is only a summary of the requirements for LEDIT.  Please refer to pages
  5777. 19-23 of your printed course notes for the actual requirements.  As a point of
  5778. reference, our solution requires about 180 lines of Ada on four pages.
  5779.  
  5780. Here are the steps to follow for Outside Assignment 5.  They can also be found
  5781. in the printed course notes on page 24:
  5782. 1HPlease type a space to go on, or B to go back.                                              2415 454B452$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1.  Carefully read the requirements starting on page 19 of the printed course
  5783.     notes.  Take your time.
  5784.  
  5785. 2.  Write the Ada code, compile, and link.  Call the main program LEDIT.  If
  5786.     you have any questions about what LEDIT should do, you can compile and run
  5787.     our solution, which is in LEDIT.ANS.
  5788.  
  5789. 3.  Refer to pages 25-27 of the printed course notes for instructions on
  5790.     testing your line editor.  If any tests are failed, go back to step 2.
  5791.  
  5792. 4.  When all the tests are passed, you've completed the assignment and will
  5793.     have a chance to compare your solution with ours.
  5794.  
  5795.  
  5796. Please type X to exit ADA-TUTR temporarily, and try Outside Assignment 5.  It
  5797. will probably take several days.  Take your time; there's no deadline.  Good
  5798. luck!
  5799. 1HPlease type X to exit, a space to go on, or B to go back.                                                             2130 455B453$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 5!
  5800.  
  5801. If you like, you can compare your solution with ours, which is in LEDIT.ANS.  A
  5802. listing starts on page 28 of your printed course notes.  Note that a single
  5803. procedure handles adding, deleting, and replacing lines.  Replacing is done by
  5804. first deleting, then adding a line.
  5805.  
  5806. Your solution might be very different from ours, but if it passed all the
  5807. tests, consider it correct.
  5808.  
  5809. Early in this course we used the generic package INTEGER_IO.  Let's now learn
  5810. how to write our own generic packages, procedures, and functions.
  5811. 1HPlease type a space to go on, or B to go back.                                              2913 456B454$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    GENERICS
  5812.  
  5813. It would be easy to write a package that creates a single stack of 10 INTEGERs,
  5814. and lets us PUSH and POP on it.  However, the code would be about the same
  5815. regardless of the size of the stack, and regardless of the type of objects on
  5816. the stack.  For example, a second package that creates a stack of 50 DATEs
  5817. would look about the same.  We can write one generic package, and instantiate
  5818. it for any size and almost any type we need.  The specification is:
  5819.  
  5820.                      generic
  5821.                         SIZE : POSITIVE;
  5822.                         type DUMMY is private;
  5823.                      package STACK_PACKAGE is
  5824.                         procedure PUSH(OBJECT : in DUMMY);
  5825.                         function POP return DUMMY;
  5826.                      end STACK_PACKAGE;
  5827.  
  5828. Since both SIZE and type DUMMY are generic, both must be specified when we
  5829. instantiate the package:
  5830.  
  5831.         package STACK_OF_10_INTEGERS is new STACK_PACKAGE(10, INTEGER);
  5832.         package STACK_OF_50_DATES    is new STACK_PACKAGE(50, DATE);
  5833. 1HPlease type a space to go on, or B to go back.                                                               3574 457B455$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If the generic part says type DUMMY is private; then the subprogram or package
  5834. body may do only three things with objects of type DUMMY: create them, assign
  5835. them, and test them for equality or inequality.  Note that this is similar to
  5836. the list of things we may do with a private type outside an ordinary package.
  5837. In this case, we're listing what we can do inside the generic package.  Calling
  5838. the package's subprograms isn't on our list, because they're not written yet!
  5839. We're listing the things we can do when we write the body of the package.  Of
  5840. course, once we write some subprograms, other subprograms can call them.
  5841.  
  5842. Although we can do only three things with objects of a private type inside a
  5843. generic package, we can instantiate that package with almost any type at all.
  5844. Our STACK_PACKAGE can be instantiated for DATEs, STRINGs (see the next
  5845. paragraph), RAINBOW_COLORs, FLOATs, and any type for which we can assign
  5846. objects and test them for equality.  That means any type except a limited
  5847. private type.  We can't instantiate STACK_PACKAGE for type TEXT_IO.FILE_TYPE
  5848. (a limited private type), because in our package we're allowed to assign and
  5849. test for equality objects of type DUMMY.
  5850.  
  5851. Since we can't create objects of an unconstrained array type, if we want to
  5852. instantiate STACK_PACKAGE for STRINGs, we must use a constrained subtype of
  5853. STRING.  For example, we could write subtype NAME is STRING(1 .. 30); and then
  5854. write package STACK_OF_50_NAMES is new STACK_PACKAGE(50, NAME);.
  5855. 1HPlease type a space to go on, or B to go back.  3136 458B456$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We could instantiate our package even for limited private types like
  5856. TEXT_IO.FILE_TYPE if the generic part had said type DUMMY is limited private;.
  5857. However, the only thing our package could do with objects of that type is
  5858. create them.  Ordinarily, that's not very useful.
  5859.  
  5860. If the generic part says type DUMMY is ( <> ); then we can instantiate the
  5861. package (or subprogram) for any discrete type.  That means any enumeration or
  5862. integer type: CHARACTER, BOOLEAN, COUNTER, NO_OF_APPLES, etc.  Inside the
  5863. package, attributes like 'FIRST are available.
  5864.  
  5865. If the generic part says type DUMMY is range <>; then we can instantiate for
  5866. any integer type.  Inside the package, we can do things that can be done with
  5867. all integer types, such as add, etc.
  5868.  
  5869. If the generic part says type DUMMY is delta <>; then we can instantiate for
  5870. any fixed point type, to be discussed in the Advanced Topics section.
  5871.  
  5872. Finally, if the generic part says type DUMMY is digits <>; then we can
  5873. instantiate for any floating point type, such as FLOAT or the REAL we created.
  5874.  
  5875. The specification of a generic subprogram must be given separately from the
  5876. body.  For example, we can't eliminate the highlighted line in this function:
  5877. 1HPlease type a space to go on, or B to go back.                                        2374 459B457$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$        generic
  5878.            type DUMMY_FLOAT is digits <>;
  5879.            type DUMMY_VECTOR is array (INTEGER range <>) of DUMMY_FLOAT;
  5880.         function SUM(V : in DUMMY_VECTOR) return DUMMY_FLOAT;
  5881.         function SUM(V : in DUMMY_VECTOR) return DUMMY_FLOAT is
  5882.           ANSWER : DUMMY_FLOAT := 0.0;
  5883.         begin
  5884.            for I in V'RANGE loop
  5885.               ANSWER := ANSWER + V(I);
  5886.             end loop;
  5887.            return ANSWER;
  5888.         end SUM;
  5889.  
  5890. We can instantiate SUM and call it as follows:
  5891.  
  5892.                 type VECTOR is array(INTEGER range <>) of FLOAT;
  5893.                 V1 : VECTOR(1 .. 10);
  5894.                 X  : FLOAT;
  5895.                 function SUMV is new SUM(FLOAT, VECTOR);
  5896.                 ...
  5897.                 X := SUMV(V1);
  5898. 1HPlease type a space to go on, or B to go back.  2024346014612462B458$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         generic
  5899.             type DUMMY is range <>;
  5900.          procedure DISPLAY(ITEM : in DUMMY);
  5901.  
  5902.          type NO_OF_APPLES is new INTEGER;
  5903.          type COUNTER is range 0 .. 1_000_000;
  5904.          type ANSWER is (YES, NO, MAYBE);
  5905.          procedure DISPLAY_APPLES   is new DISPLAY(NO_OF_APPLES);  -- 1
  5906.          procedure DISPLAY_COUNTERS is new DISPLAY(COUNTER);       -- 2
  5907.          procedure DISPLAY_ANSWERS  is new DISPLAY(ANSWER);        -- 3
  5908.  
  5909.  
  5910.          Which commented line in the above program segment is illegal?
  5911. 1HPlease press 1, 2, or 3, or B to go back.                                                    2243 463B459Q459$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         generic
  5912.             type DUMMY is range <>;
  5913.          procedure DISPLAY(ITEM : in DUMMY);
  5914.  
  5915.          type NO_OF_APPLES is new INTEGER;
  5916.          type COUNTER is range 0 .. 1_000_000;
  5917.          type ANSWER is (YES, NO, MAYBE);
  5918.          procedure DISPLAY_APPLES   is new DISPLAY(NO_OF_APPLES);  -- 1
  5919.          procedure DISPLAY_COUNTERS is new DISPLAY(COUNTER);       -- 2
  5920.          procedure DISPLAY_ANSWERS  is new DISPLAY(ANSWER);        -- 3
  5921.  
  5922.  
  5923. You're right!  When the generic part says type DUMMY is range <>;, the
  5924. procedure may be instantiated for any integer type.  ANSWER is a discrete type,
  5925. but not an integer type.
  5926. 1HPlease type a space to go on, or B or Q to go back to the question.                                 2236 463B459Q459$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         generic
  5927.             type DUMMY is range <>;
  5928.          procedure DISPLAY(ITEM : in DUMMY);
  5929.  
  5930.          type NO_OF_APPLES is new INTEGER;
  5931.          type COUNTER is range 0 .. 1_000_000;
  5932.          type ANSWER is (YES, NO, MAYBE);
  5933.          procedure DISPLAY_APPLES   is new DISPLAY(NO_OF_APPLES);  -- 1
  5934.          procedure DISPLAY_COUNTERS is new DISPLAY(COUNTER);       -- 2
  5935.          procedure DISPLAY_ANSWERS  is new DISPLAY(ANSWER);        -- 3
  5936.  
  5937.  
  5938. No, when the generic part says type DUMMY is range <>;, the procedure may be
  5939. instantiated for any integer type.  NO_OF_APPLES is a type derived from
  5940. INTEGER, so it's an integer type.
  5941. 1HPlease type a space to go on, or B or Q to go back to the question.                                        2272 463B459Q459$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$         generic
  5942.             type DUMMY is range <>;
  5943.          procedure DISPLAY(ITEM : in DUMMY);
  5944.  
  5945.          type NO_OF_APPLES is new INTEGER;
  5946.          type COUNTER is range 0 .. 1_000_000;
  5947.          type ANSWER is (YES, NO, MAYBE);
  5948.          procedure DISPLAY_APPLES   is new DISPLAY(NO_OF_APPLES);  -- 1
  5949.          procedure DISPLAY_COUNTERS is new DISPLAY(COUNTER);       -- 2
  5950.          procedure DISPLAY_ANSWERS  is new DISPLAY(ANSWER);        -- 3
  5951.  
  5952.  
  5953. No, when the generic part says type DUMMY is range <>;, the procedure may be
  5954. instantiated for any integer type.  The definition of the user-defined type
  5955. COUNTER has the word range, so COUNTER is an integer type.
  5956. 1HPlease type a space to go on, or B or Q to go back to the question.    3115 464B459$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    TASKING
  5957.  
  5958. Here are two versions of a program with two parallel tasks.  Since the main
  5959. program is a task, these two versions are equivalent.
  5960.  
  5961.          with TEXT_IO; use TEXT_IO;         with TEXT_IO; use TEXT_IO;
  5962.          procedure TASK_DEMO is                procedure TASK_DEMO is
  5963.             task A;                            task A;
  5964.             task body A is                     task body A is
  5965.             begin                              begin
  5966.                PUT_LINE("a");                     PUT_LINE("a");
  5967.                PUT_LINE("a");                     PUT_LINE("a");
  5968.             end A;                             end A;
  5969.          begin                                 task B;
  5970.             PUT_LINE("b");                     task body B is
  5971.             PUT_LINE("b");                     begin
  5972.          end TASK_DEMO;                           PUT_LINE("b");
  5973.                                                   PUT_LINE("b");
  5974.                                                end B;
  5975.                                             begin
  5976.                                                null;
  5977.                                             end TASK_DEMO;
  5978. 1HPlease type a space to go on, or B to go back.                                                             2727 465B463$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Our program could have specified as many tasks as we like.  Also, our tasks
  5979. could have declarations between task body and begin.  If the computer has
  5980. several processors, and the Ada compiler makes use of that fact, the tasks
  5981. could actually run simultaneously.  Otherwise, the compiler may (but doesn't
  5982. have to) write code to time slice among the tasks, making them appear to run
  5983. simultaneously.  One version of Ada we tried time slices, and the output of the
  5984. program looked something like this:
  5985.  
  5986. ba
  5987.  
  5988. ba
  5989.  
  5990.  
  5991. This happened because PUT_LINE is equivalent to PUT plus NEW_LINE, and thus
  5992. PUT_LINE can get interrupted before the CR-LF is output.  Here one task printed
  5993. "b", the other task printed "a", and then both tasks sent CR-LF.
  5994.  
  5995. Another implementation of Ada we tried won't time-slice unless told to with a
  5996. pragma, covered in the Advanced Topics section.  So the output of the same
  5997. program with that version of Ada looked like this:
  5998. 1HPlease type a space to go on, or B to go back.                                                 2446 466B464$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$a
  5999. a
  6000. b
  6001. b
  6002.  
  6003. In this case one task ran to completion before the other task started.  The
  6004. point is that both versions of Ada ran our program correctly, but with
  6005. different results.
  6006.  
  6007. When data is passed between tasks, we often don't want the process interrupted.
  6008. For example, suppose one task updates a record with several fields, such as a
  6009. DATE.  Another task reads the record.  We don't want the second task to
  6010. interrupt the first in the middle of updating a record.  Otherwise, the second
  6011. task might read an updated DAY field, an updated MONTH field, and an old YEAR
  6012. field, which would be meaningless.  Ada has an elegant solution to this
  6013. problem, called the rendezvous.
  6014.  
  6015. In this example, we assume that the main program created both procedure CALLER
  6016. and task SERVER, and defined type DATE:
  6017. 1HPlease type a space to go on, or B to go back.                              3173 467B465$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      procedure CALLER is          task SERVER is
  6018.          D : DATE;                    entry UPDATE(ITEM : in out DATE);
  6019.                                    end SERVER;
  6020.       begin                        task body SERVER is
  6021.          -----;                    begin
  6022.          -----;  -- Block 1           -----;  -- Block 3
  6023.          -----;                       -----;
  6024.                                       accept UPDATE(ITEM : in out DATE) do
  6025.          SERVER.UPDATE(D);               -----;  -- Block 4
  6026.                                          -----;
  6027.          -----;                       end UPDATE;
  6028.          -----;  -- Block 2           -----;  -- Block 5
  6029.          -----;                       -----;
  6030.       end CALLER;                  end SERVER;
  6031.  
  6032. Code blocks 1 and 3 run in parallel (perhaps simultaneously, as discussed).
  6033. Then CALLER waits at the call to SERVER.UPDATE while SERVER executes block 4.
  6034. Block 4 is called the critical section of code, where records might be updated,
  6035. etc.  When this rendezvous is over, blocks 2 and 5 run in parallel.  If CALLER
  6036. reaches the call before SERVER reaches accept, CALLER will wait patiently
  6037. there for SERVER.  If SERVER reaches accept first, it will wait patiently there
  6038. for a caller.
  6039. 1HPlease type a space to go on, or B to go back.   3362 468B466$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$      procedure CALLER is          task SERVER is
  6040.          D : DATE;                    entry UPDATE(ITEM : in out DATE);
  6041.                                    end SERVER;
  6042.       begin                        task body SERVER is
  6043.          -----;                    begin
  6044.          -----;  -- Block 1           -----;  -- Block 3
  6045.          -----;                       -----;
  6046.                                       accept UPDATE(ITEM : in out DATE) do
  6047.          SERVER.UPDATE(D);               -----;  -- Block 4
  6048.                                          -----;
  6049.          -----;                       end UPDATE;
  6050.          -----;  -- Block 2           -----;  -- Block 5
  6051.          -----;                       -----;
  6052.       end CALLER;                  end SERVER;
  6053.  
  6054. The call to UPDATE looks like a procedure call.  We can't use a task, so the
  6055. call requires dot notation.  The entry statement looks like a procedure
  6056. specification, with entry replacing procedure.  The task specification may have
  6057. any number of entry statements; if it has none, we write simply TASK SERVER;.
  6058. The accept block looks like a procedure without declarations, but accept
  6059. replaces procedure, and do replaces is begin.  An accept with no arguments and
  6060. no statements may be written simply as accept UPDATE;.
  6061. 1HPlease type a space to go on, or B to go back.              2546F469T470B467$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             procedure MASTER is              task SLAVE is
  6062.                                                  entry SYNC;
  6063.                                               end SLAVE;
  6064.                                               task body SLAVE is
  6065.              begin                            begin
  6066.                 -----;                           -----;
  6067.                 -----;  -- Block 1               -----;  -- Block 3
  6068.                 -----;                           -----;
  6069.                 SLAVE.SYNC;                      accept SYNC;
  6070.                 -----;                           -----;
  6071.                 -----;  -- Block 2               -----;  -- Block 4
  6072.                 -----;                           -----;
  6073.              end MASTER;                      end SLAVE;
  6074.  
  6075.  
  6076. True or False?  Statements in blocks 1 and 4 could execute simultaneously.
  6077. 1HPlease press T for true or F for false, or B to go back.                              2826 471B468Q468$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             procedure MASTER is              task SLAVE is
  6078.                                                  entry SYNC;
  6079.                                               end SLAVE;
  6080.                                               task body SLAVE is
  6081.              begin                            begin
  6082.                 -----;                           -----;
  6083.                 -----;  -- Block 1               -----;  -- Block 3
  6084.                 -----;                           -----;
  6085.                 SLAVE.SYNC;                      accept SYNC;
  6086.                 -----;                           -----;
  6087.                 -----;  -- Block 2               -----;  -- Block 4
  6088.                 -----;                           -----;
  6089.              end MASTER;                      end SLAVE;
  6090.  
  6091.  
  6092. You're right!  MASTER will wait at SLAVE.SYNC for SLAVE to reach accept, or
  6093. SLAVE will wait at accept for MASTER to reach SLAVE.SYNC;.  Therefore, blocks 1
  6094. and 4 can't execute simultaneously.
  6095. 1HPlease type a space to go on, or B or Q to go back to the question.                                                  2769 471B468Q468$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             procedure MASTER is              task SLAVE is
  6096.                                                  entry SYNC;
  6097.                                               end SLAVE;
  6098.                                               task body SLAVE is
  6099.              begin                            begin
  6100.                 -----;                           -----;
  6101.                 -----;  -- Block 1               -----;  -- Block 3
  6102.                 -----;                           -----;
  6103.                 SLAVE.SYNC;                      accept SYNC;
  6104.                 -----;                           -----;
  6105.                 -----;  -- Block 2               -----;  -- Block 4
  6106.                 -----;                           -----;
  6107.              end MASTER;                      end SLAVE;
  6108.  
  6109.  
  6110. False.  MASTER will wait at SLAVE.SYNC for SLAVE to reach accept, or SLAVE will
  6111. wait at accept for MASTER to reach SLAVE.SYNC;.  Therefore, blocks 1 and 4
  6112. can't execute simultaneously.
  6113. 1HPlease type a space to go on, or B or Q to go back to the question.       2525 472B468$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If several tasks call an entry before the server reaches accept, the calls are
  6114. queued first-in, first-out.
  6115.  
  6116. We can write a select block to accept any of several different calls:
  6117.  
  6118.                          select
  6119.                             accept A;
  6120.                          or
  6121.                             accept B(I : in INTEGER) do
  6122.                                -----;
  6123.                             end B;
  6124.                          or
  6125.                             accept C;
  6126.                          end select;
  6127.  
  6128. When select is reached, the task waits for a call to A or B or C.  If calls to
  6129. more than one entry are pending, one will be chosen arbitrarily.
  6130.  
  6131. delay statement, used in ordinary code, will delay a specified number of
  6132. seconds (plus any system overhead).  For example,
  6133. 1HPlease type a space to go on, or B to go back.                                                   2633 473B471$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                   A;
  6134.                                    delay 5.0;
  6135.                                    B;
  6136.  
  6137. will call A, delay five seconds (plus system overhead), and then call B.
  6138. However, when used in a select block, the meaning is a bit different.  It's
  6139. used to implement an impatient server.  For example,
  6140.  
  6141.                                  select
  6142.                                     accept A;
  6143.                                  or
  6144.                                     accept B;
  6145.                                  or
  6146.                                     delay 5.0;
  6147.                                     C;
  6148.                                  end select;
  6149.  
  6150. will wait up to five seconds for a call to A or B.  If no call is received, C
  6151. will be called.
  6152.  
  6153. Guards can be used to switch alternatives of a select block on and off.  For
  6154. example,
  6155. 1HPlease type a space to go on, or B to go back.                                           3142 474B472$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                J : INTEGER;
  6156.                                 ...
  6157.                                 select
  6158.                                    when J = 1 =>
  6159.                                    accept A;
  6160.                                 or
  6161.                                    when J = 2 =>
  6162.                                    accept B;
  6163.                                 end select;
  6164.  
  6165. Here A is an alternative only if the condition (J = 1) is true; B is an
  6166. alternative only if J = 2.  If J /= 1, then no call to A will be accepted, even
  6167. if one is pending.  If every branch of a select block has a guard and all
  6168. guards are false, PROGRAM_ERROR is raised.
  6169.  
  6170. Tasks "die" in three ways.  The least elegant way is for a task to abort it,
  6171. e.g., abort SERVER;.  This is drastic, because SERVER might be in the middle
  6172. of a rendezvous.  A better way is for a family of tasks each to include
  6173. terminate; as one alternative in a select block.  (A "family" of tasks is the
  6174. set of tasks created by one "parent," for example, the main program.)  When
  6175. calls to the entries in the tasks all cease, all tasks in the family will reach
  6176. the terminate alternative, and all will die together.
  6177. 1HPlease type a space to go on, or B to go back.                                  3256 475B473$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$But the most orderly way for a task to die is for it simply to reach its last
  6178. statement.  For example, task T below will continue to accept calls to T.A and
  6179. T.B until a task calls T.SHUTDOWN.  At that time, T will die.
  6180.  
  6181.            task T is                      task body T is
  6182.               entry A;                       DONE : BOOLEAN := FALSE;
  6183.               entry B;                    begin
  6184.               entry SHUTDOWN;                while not DONE loop
  6185.            end T;                               select
  6186.                                                    accept A do
  6187.                                                       -----;
  6188.                                                    end A;
  6189.                                                 or
  6190.                                                    accept B do
  6191.                                                       -----;
  6192.                                                    end B;
  6193.                                                 or
  6194.                                                    accept SHUTDOWN;
  6195.                                                    DONE := TRUE;
  6196.                                                 end select;
  6197.                                              end loop;
  6198.                                           end T;
  6199. 1HPlease type a space to go on, or B to go back.                    2950 476B474$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Trying to call an entry of a task that has died will raise TASKING_ERROR.
  6200. Also, a task can't terminate until all the tasks it creates terminate.  In
  6201. particular, the main program can't return to the operating system until all
  6202. tasks in the program have died.  Programmers must be careful to avoid possible
  6203. deadlocks.  Ada solves many problems that plague other languages, but
  6204. unfortunately the deadlock problem remains unsolved.
  6205.  
  6206. select block may have an else alternative.  Here's an example of a very
  6207. impatient server.  If a call to A or B is pending it will be served, otherwise,
  6208. C will be called:
  6209.  
  6210.                                  select
  6211.                                     accept A do
  6212.                                        -----;
  6213.                                     end A;
  6214.                                  or
  6215.                                     accept B do
  6216.                                        -----;
  6217.                                     end B;
  6218.                                  else
  6219.                                     C;
  6220.                                  end select;
  6221. 1HPlease type a space to go on, or B to go back.                          3263T477F478B475$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type DATE is ...                     task body DATA_PROTECTOR is
  6222. task DATA_PROTECTOR is                  SAVE_D : DATE;
  6223.    entry READ_DATE(D : out DATE);       DONE   : BOOLEAN := FALSE;
  6224.    entry WRITE_DATE(D : in DATE);    begin
  6225.    entry SHUTDOWN;                      accept WRITE_DATE(D : in DATE) do
  6226. end DATA_PROTECTOR;                        SAVE_D := D:
  6227.                                         end WRITE_DATE;
  6228.                                         while not DONE loop
  6229.                                            select
  6230.                                               accept READ_DATE(D : out DATE) do
  6231.                                                  D := SAVE_D;
  6232.                                               end READ_DATE;
  6233.                                            or
  6234.                                               accept WRITE_DATE(D : in DATE) do
  6235.                                                  SAVE_D := D;
  6236. True or False?  This task must                end WRITE_DATE;
  6237. serve at least one call to                 or
  6238. WRITE_DATE before it will                     accept SHUTDOWN;
  6239. accept calls to READ_DATE.                    DONE := TRUE;
  6240.                                            end select;
  6241.                                         end loop;
  6242.                                      end DATA_PROTECTOR;
  6243. 1HPlease press T for true or F for false, or B to go back.             3356 479B476Q476$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type DATE is ...                     task body DATA_PROTECTOR is
  6244. task DATA_PROTECTOR is                  SAVE_D : DATE;
  6245.    entry READ_DATE(D : out DATE);       DONE   : BOOLEAN := FALSE;
  6246.    entry WRITE_DATE(D : in DATE);    begin
  6247.    entry SHUTDOWN;                      accept WRITE_DATE(D : in DATE) do
  6248. end DATA_PROTECTOR;                        SAVE_D := D:
  6249.                                         end WRITE_DATE;
  6250.                                         while not DONE loop
  6251.                                            select
  6252.                                               accept READ_DATE(D : out DATE) do
  6253.                                                  D := SAVE_D;
  6254.                                               end READ_DATE;
  6255.                                            or
  6256.                                               accept WRITE_DATE(D : in DATE) do
  6257.                                                  SAVE_D := D;
  6258. You're right!  The extra accept               end WRITE_DATE;
  6259. block outside the loop forces us           or
  6260. to call WRITE_DATE at least once              accept SHUTDOWN;
  6261. before we can call READ_DATE.                 DONE := TRUE;
  6262.                                            end select;
  6263.                                         end loop;
  6264.                                      end DATA_PROTECTOR;
  6265. 1HPlease type a space to go on, or B or Q to go back to the question.                    3317 479B476Q476$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type DATE is ...                     task body DATA_PROTECTOR is
  6266. task DATA_PROTECTOR is                  SAVE_D : DATE;
  6267.    entry READ_DATE(D : out DATE);       DONE   : BOOLEAN := FALSE;
  6268.    entry WRITE_DATE(D : in DATE);    begin
  6269.    entry SHUTDOWN;                      accept WRITE_DATE(D : in DATE) do
  6270. end DATA_PROTECTOR;                        SAVE_D := D:
  6271.                                         end WRITE_DATE;
  6272.                                         while not DONE loop
  6273.                                            select
  6274.                                               accept READ_DATE(D : out DATE) do
  6275.                                                  D := SAVE_D;
  6276.                                               end READ_DATE;
  6277.                                            or
  6278.                                               accept WRITE_DATE(D : in DATE) do
  6279.                                                  SAVE_D := D;
  6280. True.  The extra accept block                 end WRITE_DATE;
  6281. outside the loop forces us to              or
  6282. call WRITE_DATE at least once                 accept SHUTDOWN;
  6283. before we can call READ_DATE.                 DONE := TRUE;
  6284.                                            end select;
  6285.                                         end loop;
  6286.                                      end DATA_PROTECTOR;
  6287. 1HPlease type a space to go on, or B or Q to go back to the question.                                                           2629 480B476$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The select block can be used in a caller as well as a server.  The following
  6288. block waits up to five seconds to call entry A in task T.  If T isn't ready to
  6289. accept the call in five seconds, the block calls procedure B instead.  This is
  6290. called an impatient customer:
  6291.  
  6292.                                  select
  6293.                                     T.A;
  6294.                                  or
  6295.                                     delay 5.0;
  6296.                                     B;
  6297.                                  end select;
  6298.  
  6299. A very impatient customer can be implemented with else.  This block calls T.A
  6300. only if T is ready to accept the call immediately, otherwise, it calls B.
  6301.  
  6302.                                   select
  6303.                                      T.A;
  6304.                                   else
  6305.                                      B;
  6306.                                   end select;
  6307. 1HPlease type a space to go on, or B to go back.                                               2441 481B479$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Task types may be declared.  This permits us to create an array of tasks, and
  6308. it lets us bring tasks into existence via access types.  Tasks begin executing
  6309. as soon as they're brought into existence.  For example,
  6310.  
  6311.                             task type X is
  6312.                                entry E;
  6313.                             end X;
  6314.                             type P is access X;
  6315.                             X1 : P;
  6316.                             A : array(1 .. 10) of X;
  6317.                             task body X is
  6318.                                ...
  6319.                             end X;
  6320.  
  6321. Entries to these tasks are called thus:
  6322.  
  6323.                             A(5).E;
  6324.                             X1 := new X;
  6325.                             X1.all.E; or just X1.E;
  6326. 1HPlease type a space to go on, or B to go back.                                   2435 482B480$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Ada comes with a package CALENDAR; the specification is in section 9.6 of the
  6327. LRM.  The part that concerns us here is shown below.  Type DURATION is a fixed
  6328. point type built into Ada; the delay statement discussed earlier takes an
  6329. object of type DURATION.
  6330.  
  6331.         package CALENDAR is
  6332.            type TIME is private;
  6333.            function CLOCK return TIME;
  6334.            function "+"(LEFT : TIME; RIGHT : DURATION) return TIME;
  6335.            function "-"(LEFT : TIME; RIGHT : TIME)     return DURATION;
  6336.            ...
  6337.         end CALENDAR;
  6338.  
  6339. Not shown are a few other operators, and subprograms to convert between type
  6340. TIME and the year, month, day, and number of seconds since midnight.
  6341.  
  6342. Let's write a program segment that uses CALENDAR and calls A every five
  6343. seconds:
  6344. 1HPlease type a space to go on, or B to go back.                                         2627 483B481$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       with CALENDAR; use CALENDAR;
  6345.                        ...
  6346.                        NEXT_EVENT : TIME := CLOCK + 5.0;
  6347.                        ...
  6348.                        loop
  6349.                           delay NEXT_EVENT - CLOCK;
  6350.                           A;
  6351.                           NEXT_EVENT := NEXT_EVENT + 5.0;
  6352.                        end loop;
  6353.  
  6354. Note that this loop accounts for the time required to call A.  Instead of
  6355. delaying 5.0, we calculate the time of the next call in NEXT_EVENT, and delay
  6356. that time minus the current time, which we obtain by calling CLOCK.  Thus the
  6357. program will go through the loop once every 5.0 seconds, even if it takes a
  6358. little time to call A.
  6359.  
  6360. The - and + operators inside the loop both use infix functions from CALENDAR.
  6361.  
  6362. We're now ready for Outside Assignment 6!  It will be much simpler than Outside
  6363. Assignment 5.
  6364. 1HPlease type a space to go on, or B to go back.                                                 2840 484B482$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                   OUTSIDE ASSIGNMENT 6 - EXERCISE IN TASKING
  6365.  
  6366. On page 32 of your printed course notes is a listing of TASKING.DUM.  This
  6367. program calls a task entry to print Tick! on the screen every five seconds
  6368. until it has been printed nine times.
  6369.  
  6370. Every time delay is executed, there's a call to NEW_LINE, so that the delay
  6371. will be visible on the screen.  The program is entirely in lower case, because
  6372. your assignment is to modify it.  If you make your modifications in upper case,
  6373. it will be easy to see what you changed.
  6374.  
  6375. We want you to change the declaration of T from a single task to an array of
  6376. three tasks.  The tasks are numbered 1, 2, and 3.  Task 1 is to be activated
  6377. every two five-second intervals.  Task 2 is to be activated every three five-
  6378. -second intervals, and task 3, every four.  Also, instead of printing Tick!,
  6379. each task will identify itself by number, for example, Task number 3 is
  6380. starting.  Output should look as shown on page 34 of your printed notes.
  6381. 1HPlease type a space to go on, or B to go back.                                    2246 485B483$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We recommend that you create an array of three counters.  Each counter counts
  6382. down from its period (2, 3, or 4) to zero by one count every interval.  When a
  6383. counter reaches zero, the corresponding task entry is called, and the counter
  6384. is reset to its period.  All three counters should be initialized to zero, so
  6385. that all three tasks print their messages immediately upon activation of the
  6386. program.  You should use the rendezvous mechanism to inform each task of its
  6387. number (1, 2, or 3).  Your program should do an orderly shutdown of all three
  6388. tasks at the end.
  6389.  
  6390. Here are the steps to follow for Outside Assignment 6.  They're also in your
  6391. printed course notes on page 33:
  6392. 1HPlease type a space to go on, or B to go back.                              2334 486B484$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1.  Make a copy of TASKING.DUM by typing COPY TASKING.DUM TASKING.ADA.
  6393.     Compile, link, and execute the program to make sure it prints Tick! nine
  6394.     times.
  6395.  
  6396. 2.  Edit TASKING.ADA to become your solution.  Make your changes in upper case.
  6397.  
  6398. 3.  Compile TASKING.ADA, link, and execute.
  6399.  
  6400. 4.  Compare your output with page 34 of the printed course notes.  If there are
  6401.     any errors, go back to step 2.
  6402.  
  6403. 5.  When your output agrees with the printed course notes, you've finished the
  6404.     assignment and will have a chance to compare your solution with ours.
  6405.  
  6406.  
  6407. Please type X to exit ADA-TUTR temporarily, and try Outside Assignment 6.  Work
  6408. at your own pace; there's no deadline.  Good luck!
  6409. 1HPlease type X to exit, a space to go on, or B to go back.                                          1855 487B485$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              Congratulations on Completing Outside Assignment 6!
  6410.  
  6411. If you like, you can compare your solution with ours, which is in TASKING.ANS.
  6412. A listing is on page 35 of your printed course notes.  Your solution might be
  6413. different from ours, but if your output agrees with page 34 of the printed
  6414. notes, your solution is correct.
  6415.  
  6416. You've learned a great deal of Ada!  Let's go on to discuss some advanced
  6417. topics.
  6418. 1HPlease type a space to go on, or B to go back.                     2732 488B486$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    RENAMING
  6419.  
  6420. A subprogram can be renamed in Ada.  This allows us to avoid the dot notation
  6421. without a use clause.  For example, if our program withs TEXT_IO, we can write:
  6422.  
  6423.          procedure PRINT(OBJECT : in STRING) renames TEXT_IO.PUT_LINE;
  6424.  
  6425. We can now call PRINT instead of TEXT_IO.PUT_LINE.  The old name is still
  6426. available.  Note that renaming can change the names of the formal parameters
  6427. ("dummy arguments").  Renaming may also add, delete, or change default values.
  6428. When used in a package, a renaming declaration like the above goes in the
  6429. specification, not the body.
  6430.  
  6431. We can also rename task entries as procedures.  This is the only way to avoid
  6432. the dot notation when calling a task entry.
  6433.  
  6434. A function can be renamed as an infix operator, if it has the right number and
  6435. types of arguments.  Also, an infix operator can be renamed as a function.  For
  6436. example, earlier we defined type VECTOR and wrote:
  6437. 1HPlease type a space to go on, or B to go back.                                            2667 489B487$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              function "*"(LEFT, RIGHT : in VECTOR) return FLOAT;
  6438.  
  6439. This could be renamed as follows:
  6440.  
  6441.         function DOT_PRODUCT(X, Y : in VECTOR) return FLOAT renames "*";
  6442.  
  6443. Renaming can get around the restriction that library subprograms can't be infix
  6444. operators.  We can use a normal function name for the library, and rename it as
  6445. an infix operator for our program.  Similarly, we can get around the rule that
  6446. library subprograms can't overload each other.  We can give subprograms
  6447. different names in the library, and rename them in our program to overload each
  6448. other.
  6449.  
  6450. An attribute that takes an argument, such as PRED and SUCC, can be renamed as a
  6451. function.  Record components can be renamed.  If D is of the type DATE we had
  6452. earlier, we can write J : INTEGER renames D.YEAR;.  Exceptions can also be
  6453. renamed, as in
  6454.  
  6455.                   OOPS : exception renames TEXT_IO.NAME_ERROR;
  6456. 1HPlease type a space to go on, or B to go back.         3414 490B488$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          PACKAGES STANDARD AND ASCII
  6457.  
  6458. Ada comes with a package STANDARD.  However, unlike all the other packages,
  6459. STANDARD is needed by every Ada compilation unit.  Therefore, STANDARD is
  6460. automatically withed and used in every compilation.  It need not be mentioned
  6461. in a context clause.  STANDARD contains the definitions built into the Ada
  6462. language, such as type BOOLEAN is (FALSE, TRUE);.  A listing of the package
  6463. specification is in Appendix C of the LRM.  Thus, the full name for the type
  6464. BOOLEAN is STANDARD.BOOLEAN, the full name for INTEGER is STANDARD.INTEGER,
  6465. etc.  Naturally, this normally need not concern the programmer.  The dot
  6466. notation is automatic because STANDARD is automatically used in every
  6467. compilation.
  6468.  
  6469. However, inside package STANDARD is a package ASCII.  Since this package is
  6470. part of STANDARD, we never have to write a with clause for it.  But ASCII isn't
  6471. automatically used.  If we want the dot notation for ASCII to be automatic, we
  6472. have to provide a use clause.  As the listing in the LRM shows, ASCII contains
  6473. names for all the unprintable ASCII characters, such as BEL, ESC, etc.  It also
  6474. provides names for many punctuation marks, in case your terminal or printer
  6475. doesn't have them.  For example, DOLLAR, AT_SIGN, etc.  Finally, it provides
  6476. names for all lower case letters, from LC_A to LC_Z.
  6477. 1HPlease type a space to go on, or B to go back.                                                              2159 491B489$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$For example, either of the following programs will print a@b and ring the bell
  6478. or beep the terminal:
  6479.  
  6480.        with TEXT_IO; use TEXT_IO;
  6481.        procedure AB is
  6482.        begin
  6483.           PUT_LINE(ASCII.LC_A & ASCII.AT_SIGN & ASCII.LC_B & ASCII.BEL);
  6484.        end AB;
  6485.  
  6486.        with TEXT_IO; use TEXT_IO;
  6487.        procedure AB is
  6488.           use ASCII;
  6489.        begin
  6490.           PUT_LINE(LC_A & AT_SIGN & LC_B & BEL);
  6491.        end AB;
  6492.  
  6493. Note the placement of use ASCII; in the second example.  It's similar to the
  6494. placement of use MY_INT_IO; in ADD.ADA, which we discussed early in the course.
  6495. 1HPlease type a space to go on, or B to go back.                 2863 492B490$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        AN ALTERNATIVE TO INFIX NOTATION
  6496.  
  6497. Earlier we learned to define and use infix operators like
  6498.  
  6499.               type VECTOR is array(INTEGER range <>) of FLOAT;
  6500.               function "*"(LEFT, RIGHT : in VECTOR) return FLOAT;
  6501.               A, B : VECTOR(1 .. 10);
  6502.               F    : FLOAT;
  6503.               ...
  6504.               F := A * B;
  6505.  
  6506. An alternative notation equivalent to F := A * B; is F := "*"(A, B);.  Why
  6507. would anyone want to use this clumsier notation?  If our function is in a
  6508. package MATH that the calling program withs but for some reason doesn't use, we
  6509. could use dot notation and write F := MATH."*"(A, B);.  But we couldn't use dot
  6510. notation directly with infix operators, as in F := A MATH.* B; or even
  6511. F := A MATH."*" B;.  Both of those are illegal.  The alternative notation is
  6512. also used to emphasize that an operator comes from package STANDARD.  For
  6513. example, if I, J, and K are INTEGERs, we could write I := STANDARD."*"(J, K);,
  6514. which is equivalent to I := J * K;.
  6515. 1HPlease type a space to go on, or B to go back.             1558249314943495B491$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Assuming X, Y, and Z have been declared FLOAT, which one of the following is
  6516. illegal?
  6517.  
  6518.                           1.  X := Y / Z;
  6519.  
  6520.                           2.  X := Y STANDARD."/" Z;
  6521.  
  6522.                           3.  X := STANDARD."/"(Y, Z);
  6523. 1HPlease press 1, 2, or 3, or B to go back.                  1757 496B492Q492$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          1.  X := Y / Z;
  6524.  
  6525.                           2.  X := Y STANDARD."/" Z;
  6526.  
  6527.                           3.  X := STANDARD."/"(Y, Z);
  6528.  
  6529.  
  6530. You're right!  The syntax of number 2 is illegal.  To specify the package
  6531. STANDARD, we have to use the syntax of number 3.  Normally, of course, the
  6532. syntax of number 1 is used.
  6533. 1HPlease type a space to go on, or B or Q to go back to the question.                   1614 496B492Q492$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          1.  X := Y / Z;
  6534.  
  6535.                           2.  X := Y STANDARD."/" Z;
  6536.  
  6537.                           3.  X := STANDARD."/"(Y, Z);
  6538.  
  6539.  
  6540. No, number 1 is the syntax that would ordinarily be used for division, and is
  6541. legal.
  6542. 1HPlease type a space to go on, or B or Q to go back to the question.                                                              1564 496B492Q492$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          1.  X := Y / Z;
  6543.  
  6544.                           2.  X := Y STANDARD."/" Z;
  6545.  
  6546.                           3.  X := STANDARD."/"(Y, Z);
  6547.  
  6548.  
  6549. No, number 3 is the correct way to specify package STANDARD explicitly.
  6550. 1HPlease type a space to go on, or B or Q to go back to the question.            2637 497B492$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                    RECORD DISCRIMINANTS AND RECORD VARIANTS
  6551.  
  6552. The definition of a record type can have discriminants, which have the same
  6553. form as formal parameters ("dummy arguments") of subprograms, except that the
  6554. mode is omitted.  Default values may be supplied.  For example,
  6555.  
  6556.        type MATRIX is array(INTEGER range <>, INTEGER range <>) of FLOAT;
  6557.        type SQUARE_MATRIX(SIZE : POSITIVE := 9) is
  6558.           record
  6559.              SQ : MATRIX(1 .. SIZE, 1 .. SIZE);
  6560.           end record;
  6561.  
  6562. Although objects of type MATRIX can be rectangular, objects of type
  6563. SQUARE_MATRIX must be square.  In declaring these objects, we use the same
  6564. syntax as a subprogram call, with either positional or named notation:
  6565.  
  6566.     A : SQUARE_MATRIX(7);  -- a 7-by-7 matrix
  6567.     B : SQUARE_MATRIX(SIZE => 5);  -- a 5-by-5 matrix
  6568.     C : SQUARE_MATRIX;  -- a 9-by-9 matrix, using the default value of SIZE
  6569. 1HPlease type a space to go on, or B to go back.                                       2938 498B496$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Of course, subtypes of discriminated records can be declared.  For example,
  6570.  
  6571.                 subtype CHESS_BOARD is SQUARE_MATRIX(SIZE => 8);
  6572.  
  6573. A record discriminant is used in the definition of type TEXT in the
  6574. TEXT_HANDLER package specification of section 7.6 of the LRM:
  6575.  
  6576.                   MAXIMUM : constant := ... ;
  6577.                   subtype INDEX is INTEGER range 0 .. MAXIMUM;
  6578.                   ...
  6579.                   type TEXT(MAXIMUM_LENGTH : INDEX) is
  6580.                      record
  6581.                         POS   : INDEX := 0;
  6582.                         VALUE : STRING(1 .. MAXIMUM_LENGTH);
  6583.                      end record;
  6584.  
  6585. With the simplified version of type TEXT presented earlier, every object of
  6586. type TEXT occupied enough memory for the longest string we expected to handle
  6587. (e.g., 80 characters).  With this version, each object of type TEXT that we
  6588. create can have just the MAXIMUM_LENGTH we need, and its effective length POS
  6589. can vary from zero to that MAXIMUM_LENGTH.  The record discriminant complicates
  6590. the package specification only very slightly; see section 7.6 of the LRM.
  6591. 1HPlease type a space to go on, or B to go back.                                      2972 499B497$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The definition of a record type can have a variant, which also has the same
  6592. form as a subprogram formal parameter without the mode.  However, the syntax of
  6593. case construct is used to specify part of the record.  Although a record can
  6594. have several discriminants, it can have only one variant, and the variant part
  6595. must appear last in the record.  For example,
  6596.  
  6597.                         type SEX_TYPE is (MALE, FEMALE);
  6598.                         type PERSON(SEX : SEX_TYPE) is
  6599.                            record
  6600.                               AGE : NATURAL;
  6601.                               case SEX is
  6602.                                  when MALE =>
  6603.                                     BEARDED => BOOLEAN;
  6604.                                  when FEMALE =>
  6605.                                     CHILDREN : NATURAL;
  6606.                               end case;
  6607.                            end record;
  6608.  
  6609. If the sex of the person is MALE, we want the record to include a BOOLEAN
  6610. showing whether he's bearded, but if the sex is FEMALE, we want the record to
  6611. include an INTEGER (subtype NATURAL), showing the number of children she has.
  6612. 1HPlease type a space to go on, or B to go back.    2761 500B498$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        type SEX_TYPE is (MALE, FEMALE);
  6613.                         type PERSON(SEX : SEX_TYPE) is
  6614.                            record
  6615.                               AGE : NATURAL;
  6616.                               case SEX is
  6617.                                  when MALE =>
  6618.                                     BEARDED => BOOLEAN;
  6619.                                  when FEMALE =>
  6620.                                     CHILDREN : NATURAL;
  6621.                               end case;
  6622.                            end record;
  6623.  
  6624. Objects are declared and given values as we'd expect:
  6625.  
  6626.    JOHN : PERSON(SEX => MALE) := (SEX => MALE, AGE => 21, BEARDED => FALSE);
  6627.    MARY : PERSON(SEX => FEMALE) := (SEX => FEMALE, AGE => 18, CHILDREN => 0);
  6628.  
  6629. Attempting to access JOHN.CHILDREN or MARY.BEARDED will raise CONSTRAINT_ERROR.
  6630. To simplify the object declarations, subtypes may be declared:
  6631.  
  6632.                         subtype MAN is PERSON(MALE);
  6633.                         subtype WOMAN is PERSON(FEMALE);
  6634. 1HPlease type a space to go on, or B to go back.               214225011502B499$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type COMPUTER_SIZE is (HANDHELD,LAPTOP,PORTABLE,DESKTOP,MAINFRAME,CLUSTER);
  6635. type COMPUTER(SIZE : COMPUTER_SIZE) is
  6636.    record
  6637.       K_MEM : POSITIVE;
  6638.       DISKS : NATURAL;
  6639.       case SIZE is
  6640.          when CLUSTER =>
  6641.             NUMBER_OF_UNITS : POSITIVE;
  6642.             DATA_RATE       : FLOAT;
  6643.          when others =>
  6644.             null;
  6645.       end case;
  6646.    end record;
  6647. MY_PC       : COMPUTER(DESKTOP) := (DESKTOP, K_MEM => 640, DISKS => 2);    -- 1
  6648. COMPANY_LAN : COMPUTER(CLUSTER) := (CLUSTER, K_MEM => 24576, DISKS => 8);  -- 2
  6649.  
  6650. Which commented declaration in the above program is illegal?
  6651. 1HPlease press 1 or 2, or B to go back.                                  2249 503B500Q500$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type COMPUTER_SIZE is (HANDHELD,LAPTOP,PORTABLE,DESKTOP,MAINFRAME,CLUSTER);
  6652. type COMPUTER(SIZE : COMPUTER_SIZE) is
  6653.    record
  6654.       K_MEM : POSITIVE;
  6655.       DISKS : NATURAL;
  6656.       case SIZE is
  6657.          when CLUSTER =>
  6658.             NUMBER_OF_UNITS : POSITIVE;
  6659.             DATA_RATE       : FLOAT;
  6660.          when others =>
  6661.             null;
  6662.       end case;
  6663.    end record;
  6664. MY_PC       : COMPUTER(DESKTOP) := (DESKTOP, K_MEM => 640, DISKS => 2);    -- 1
  6665. COMPANY_LAN : COMPUTER(CLUSTER) := (CLUSTER, K_MEM => 24576, DISKS => 8);  -- 2
  6666.  
  6667. You're right!  The initialization of COMPANY_LAN fails to include fields for
  6668. NUMBER_OF_UNITS and DATA_RATE.
  6669. 1HPlease type a space to go on, or B or Q to go back to the question.                           2348 503B500Q500$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$type COMPUTER_SIZE is (HANDHELD,LAPTOP,PORTABLE,DESKTOP,MAINFRAME,CLUSTER);
  6670. type COMPUTER(SIZE : COMPUTER_SIZE) is
  6671.    record
  6672.       K_MEM : POSITIVE;
  6673.       DISKS : NATURAL;
  6674.       case SIZE is
  6675.          when CLUSTER =>
  6676.             NUMBER_OF_UNITS : POSITIVE;
  6677.             DATA_RATE       : FLOAT;
  6678.          when others =>
  6679.             null;
  6680.       end case;
  6681.    end record;
  6682. MY_PC       : COMPUTER(DESKTOP) := (DESKTOP, K_MEM => 640, DISKS => 2);    -- 1
  6683. COMPANY_LAN : COMPUTER(CLUSTER) := (CLUSTER, K_MEM => 24576, DISKS => 8);  -- 2
  6684.  
  6685. No, the declaration of MY_PC and its initialization are correct.  The others
  6686. clause of the case applies, so there are only two fields in the record when
  6687. SIZE is DESKTOP.
  6688. 1HPlease type a space to go on, or B or Q to go back to the question.                            2827 504B500$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                        FIXED POINT AND UNIVERSAL TYPES
  6689.  
  6690. The only fixed point type defined in package STANDARD is DURATION.  However,
  6691. Ada lets us define our own fixed point types.  We specify the accuracy with the
  6692. reserved word delta, and a range constraint is required.  For example,
  6693.  
  6694.                 type VOLTAGE is delta 0.01 range -20.0 .. 20.0;
  6695.  
  6696. This guarantees that the objects of type VOLTAGE will be represented with at
  6697. least an accuracy of 1/100.  Since the computer is binary, Ada will choose an
  6698. internal representation at least as accurate as 1/128.  It might use even
  6699. greater accuracy, for example, 1/256.  In any event, it's guaranteed that the
  6700. accuracy is at least as good as that requested.
  6701.  
  6702. It's possible to make a request that a particular implementation of Ada can't
  6703. handle.  For example, if we write
  6704.  
  6705.                type VOLTAGE is delta 1.0E-10 range 0.0 .. 1.0E9;
  6706.  
  6707. the version of Ada we're using may have to report that it has no internal
  6708. representation that satisfies this requirement.
  6709. 1HPlease type a space to go on, or B to go back.                                                 2771 505B503$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                type VOLTAGE is delta 0.01 range -20.0 .. 20.0;
  6710.  
  6711. The set of numbers that can be represented exactly by any Ada that accepts a
  6712. type definition like the above is called the model numbers of that type.  This
  6713. applies to floating types as well as fixed, for example,
  6714.  
  6715.                      type W is digits 5 range 0.0 .. 100.0;
  6716.  
  6717. A particular implementation may represent additional numbers exactly; these are
  6718. called safe numbers.  The safe numbers are a superset of the model numbers;
  6719. their range usually is a little larger.
  6720.  
  6721. We can add and subtract objects of a fixed point type.  However, if we multiply
  6722. or divide them, we must immediately convert the result to the same or another
  6723. numeric type before we can store it.  For example,
  6724.  
  6725.                        V1, V2, V3 : VOLTAGE;
  6726.                        ...
  6727.                        V1 := V2 + V3;  -- legal
  6728.                        V1 := V2 * V3;  -- illegal
  6729.                        V1 := VOLTAGE(V2 * V3);  -- legal
  6730. 1HPlease type a space to go on, or B to go back.     2773 506B504$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$TEXT_IO contains a generic package FIXED_IO for I/O of fixed point types.
  6731.  
  6732. When we declare a variable in Ada, we give its type.  But when we declare a
  6733. constant, we may or may not give its type.  For example,
  6734.  
  6735.                     L  : constant INTEGER := 30;
  6736.                     M  : constant := 1000;
  6737.                     E  : constant FLOAT := 2.718281828;
  6738.                     PI : constant := 3.141592654;
  6739.  
  6740. Also, when we write a number, such as 3.0 or 29_999, we usually don't qualify
  6741. it with a type (for example, FLOAT'(3.0)).
  6742.  
  6743. Suppose an implementation of Ada provides types INTEGER, LONG_INTEGER, FLOAT,
  6744. and LONG_FLOAT.  How can Ada determine the types of M, PI, 3.0, and 29_999?  M
  6745. and 29_999 are said to be of type universal_integer; they can assume any
  6746. integer type as required.  PI and 3.0 are said to be of type universal_real and
  6747. can assume any floating or fixed point type as required.
  6748.  
  6749. We can't explicitly declare objects to be of universal types.  However, we can
  6750. write
  6751. 1HPlease type a space to go on, or B to go back.   2825 507B505$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                         M  : constant := 1000;
  6752.                          PI : constant := 3.141592654;
  6753.                          I : INTEGER;
  6754.                          J : LONG_INTEGER;
  6755.                          F : FLOAT;
  6756.                          G : LONG_FLOAT;
  6757.                          ...
  6758.                          I := M;  J := M;
  6759.                          I := 29_999;  J := 29_999;
  6760.                          F := PI;  G := PI;
  6761.                          F := 3.0;  G := 3.0;
  6762.  
  6763. and in each case the constant assumes the correct type.  The result of
  6764. multiplying or dividing two numbers of a fixed point type is said to be of type
  6765. universal_fixed.  This result must be explicitly converted to some numeric
  6766. type before it can be stored.
  6767.  
  6768. Most of the attributes that produce integer results, like POS, are of type
  6769. universal_integer.  For example, with the declarations above, we could write
  6770.  
  6771.                             I := CHARACTER'POS('A');
  6772.                             J := CHARACTER'POS('A');
  6773. 1HPlease type a space to go on, or B to go back.                                                   16363508150925104511B506$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Which one of the following declarations is illegal?
  6774.  
  6775.  
  6776.               1.   type RATE is digits 6;
  6777.  
  6778.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  6779.  
  6780.               3.   type CURRENT is delta 0.1;
  6781.  
  6782.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  6783. 1HPlease press 1, 2, 3, or 4, or B to go back.                                        1726 512B507Q507$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.   type RATE is digits 6;
  6784.  
  6785.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  6786.  
  6787.               3.   type CURRENT is delta 0.1;
  6788.  
  6789.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  6790.  
  6791.  
  6792. You're right!  A fixed point type declaration must have a range constraint.
  6793. 1HPlease type a space to go on, or B or Q to go back to the question.                                                  1730 512B507Q507$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.   type RATE is digits 6;
  6794.  
  6795.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  6796.  
  6797.               3.   type CURRENT is delta 0.1;
  6798.  
  6799.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  6800.  
  6801.  
  6802. No, number 1 is legal.  A user defined floating point type need not have a
  6803. range constraint.
  6804. 1HPlease type a space to go on, or B or Q to go back to the question.                                              1725 512B507Q507$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.   type RATE is digits 6;
  6805.  
  6806.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  6807.  
  6808.               3.   type CURRENT is delta 0.1;
  6809.  
  6810.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  6811.  
  6812.  
  6813. No, number 2 is legal.  A user defined floating point type may have a range
  6814. constraint.
  6815. 1HPlease type a space to go on, or B or Q to go back to the question.                                                   1722 512B507Q507$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$              1.   type RATE is digits 6;
  6816.  
  6817.               2.   type DISTANCE is digits 6 range 0.0 .. 1.0E6;
  6818.  
  6819.               3.   type CURRENT is delta 0.1;
  6820.  
  6821.               4.   type TEMP is delta 0.05 range -200.0 .. 450.0;
  6822.  
  6823.  
  6824. No, number 4 is legal.  A fixed point type declaration must have a range
  6825. constraint.
  6826. 1HPlease type a space to go on, or B or Q to go back to the question.                                                      3351 513B507$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                MORE ATTRIBUTES
  6827.  
  6828. Ada provides a wide variety of attributes.  All of them are listed and defined
  6829. in Appendix A of the LRM.  The most important ones that we haven't yet
  6830. discussed are these:
  6831.  
  6832. FIRST and LAST can be used with any scalar type or subtype (including floating
  6833. and fixed), not just discrete types and subtypes.  For example, FLOAT'LAST is
  6834. the highest number your particular Ada represents with type FLOAT.
  6835.  
  6836. For any real type or subtype (floating or fixed), SMALL and LARGE are the
  6837. smallest and largest positive model numbers.  Thus FLOAT'SMALL is the
  6838. difference between zero and the next larger number in type FLOAT.  Also, for
  6839. any floating point (sub)type, EPSILON is the difference between one and the
  6840. next larger number.  We'll use EPSILON in a generic function later.
  6841.  
  6842. For a floating point (sub)type, DIGITS returns the value given for digits in
  6843. the declaration, and for a fixed point (sub)type, DELTA returns the value given
  6844. for delta in the declaration.  These attributes may not seem too useful,
  6845. because the programmer already knows what he wrote in the declarations.
  6846. However, they're used in generic packages and subprograms.  For example, if the
  6847. generic part says type DUMMY is delta <>;, the body can use DUMMY'DELTA.
  6848. 1HPlease type a space to go on, or B to go back.                         3545 514B512$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$For any discrete (sub)type, WIDTH gives the maximum length that the attribute
  6849. IMAGE can produce.  For example, with our earlier definition of RAINBOW_COLOR,
  6850. RAINBOW_COLOR'WIDTH is 6.  For versions of Ada using 16-bit INTEGERs,
  6851. INTEGER'WIDTH is also 6.  BOOLEAN'WIDTH is 5.
  6852.  
  6853. COUNT is used with the name of a task entry.  It returns the number of calls
  6854. presently queued on the entry.  TERMINATED is of type BOOLEAN.  It's used with
  6855. a task name, and tells if the task is terminated.
  6856.  
  6857. Let's write a generic function to compute the square root for any floating
  6858. point type, using Newton-Raphson iteration.  This method simply says that if G
  6859. is a guess of the square root of X, the next guess is the average of G and X/G.
  6860. For example, if we want to compute the square root of 9.0 and our first guess
  6861. is 9.0, successive guesses are 5.0, 3.4, 3.02352941, 3.00009155, 3.00000000.
  6862. Note that convergence is very rapid.  However, the problem in writing a program
  6863. is knowing when to stop the iteration.  We'll use the attribute EPSILON.  Since
  6864. G*G/X should be 1.0, we'll quit when the difference between G*G/X and 1.0 is
  6865. less than or equal to 3.0 times EPSILON.  Recall that DUMMY'EPSILON is the
  6866. difference between 1.0 and the next higher number for type DUMMY.  If we use
  6867. 1.0 times EPSILON, the loop might never terminate, and if we use 10.0 times
  6868. EPSILON, we might not get full precision.  So we'll use 3.0 times EPSILON.
  6869. Here's our function:
  6870. 1HPlease type a space to go on, or B to go back.                               2351 515B513$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  generic
  6871.      type DUMMY is digits <>;
  6872.   function SQRT(X :in DUMMY) return DUMMY;
  6873.   function SQRT(X :in DUMMY) return DUMMY is
  6874.      GUESS : DUMMY := X;
  6875.   begin
  6876.      if X < 0.0 then
  6877.         raise NUMERIC_ERROR;
  6878.      end if;
  6879.      while X /= 0.0 and then abs(GUESS*GUESS/X - 1.0) > 3.0*DUMMY'EPSILON loop
  6880.         GUESS := (X/GUESS + GUESS) * 0.5;
  6881.      end loop;
  6882.      return GUESS;
  6883.   end SQRT;
  6884.  
  6885. We tested our SQRT with a version of Ada having types FLOAT, LONG_FLOAT, and
  6886. LONG_LONG_FLOAT.  The last gives at least 33 decimal digits of precision.  SQRT
  6887. was instantiated for all three floating point types, as was FLOAT_IO to display
  6888. the results.  When tested with the three types, all displayed digits of the
  6889. answers were correct.
  6890. 1HPlease type a space to go on, or B to go back.                         3235 516B514$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          SEQUENTIAL_IO AND DIRECT_IO
  6891.  
  6892. TEXT_IO creates, reads and writes text files that can be typed on the screen or
  6893. printed.  Ada also provides packages SEQUENTIAL_IO and DIRECT_IO, which create,
  6894. read, and write binary files.  These files usually can't be typed or printed,
  6895. but they tend to be more efficient than text files, because the computer
  6896. doesn't have to convert numbers between its internal representation and ASCII
  6897. to read and write binary files.
  6898.  
  6899. SEQUENTIAL_IO and DIRECT_IO are both generic, and can be instantiated for any
  6900. type.  The specifications are in sections 14.2.3 and 14.2.5 of the LRM.  Like
  6901. TEXT_IO, they have procedures to CREATE, OPEN, and CLOSE files, but the I/O
  6902. procedures are called READ and WRITE, rather than PUT, GET, PUT_LINE, and
  6903. GET_LINE.  SEQUENTIAL_IO always reads and writes sequentially, but DIRECT_IO is
  6904. capable of random access.  In DIRECT_IO, an optional extra argument in READ and
  6905. WRITE tells the procedure the position in the file to read FROM or write TO.
  6906.  
  6907. TEXT_IO and instantiations of SEQUENTIAL_IO and DIRECT_IO each define their own
  6908. FILE_TYPE, so we can't open a file with one package and then do I/O with
  6909. another.  DIRECT_IO provides a FILE_MODE of INOUT_FILE as well as the usual
  6910. IN_FILE and OUT_FILE.
  6911. 1HPlease type a space to go on, or B to go back.                                         2714 517B515$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$If you like, you can examine the file ADA-TUTR.ADA for an example of the use of
  6912. DIRECT_IO.  ADA-TUTR creates a subtype for a block of characters and then
  6913. instantiates DIRECT_IO for that subtype.  It then opens ADA-TUTR.DAT with mode
  6914. IN_FILE so that it can read blocks of characters by random access.  This
  6915. enables ADA-TUTR to find and display any screen quickly.  The preliminary
  6916. comments in ADA-TUTR.ADA describe the format of the data file ADA-TUTR.DAT in
  6917. detail.
  6918.  
  6919. You may also want to examine the files DAT2TXT.ADA and TXT2DAT.ADA.  These two
  6920. programs are used when installing ADA-TUTR on non-PC computers.  Their use is
  6921. described on page 5 of your printed course notes.  They with both TEXT_IO and
  6922. DIRECT_IO, because they access a text file as well as a random access file.
  6923. However, to avoid confusion between the two packages, they use neither TEXT_IO
  6924. nor the instantiation of DIRECT_IO.  Dot notation is used instead.
  6925. 1HPlease type a space to go on, or B to go back.                                                              1839151825193520B516$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Which commented line is illegal?
  6926.  
  6927.     with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO, SEQUENTIAL_IO;  -- 1
  6928.     procedure IO is
  6929.        subtype LINE is STRING(1 .. 80);
  6930.        type SCREEN is array(1 .. 24) of LINE;
  6931.        package LINE_IO is new SEQUENTIAL_IO(LINE); use LINE_IO;  -- 2
  6932.        package SCREEN_IO is new SEQUENTIAL_IO(SCREEN); use SCREEN_IO;  -- 3
  6933.     begin
  6934.        null;
  6935.     end IO;
  6936. 1HPlease press 1, 2, or 3, or B to go back.                                     2169 521B517Q517$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO, SEQUENTIAL_IO;  -- 1
  6937.     procedure IO is
  6938.        subtype LINE is STRING(1 .. 80);
  6939.        type SCREEN is array(1 .. 24) of LINE;
  6940.        package LINE_IO is new SEQUENTIAL_IO(LINE); use LINE_IO;  -- 2
  6941.        package SCREEN_IO is new SEQUENTIAL_IO(SCREEN); use SCREEN_IO;  -- 3
  6942.     begin
  6943.        null;
  6944.     end IO;
  6945.  
  6946. You're right!  We can't use a generic package, only its instantiations,
  6947. because we can't call the subprograms in a generic package.  The first line
  6948. should read
  6949.  
  6950.                 with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO;  -- 1
  6951. 1HPlease type a space to go on, or B or Q to go back to the question.       1912 521B517Q517$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO, SEQUENTIAL_IO;  -- 1
  6952.     procedure IO is
  6953.        subtype LINE is STRING(1 .. 80);
  6954.        type SCREEN is array(1 .. 24) of LINE;
  6955.        package LINE_IO is new SEQUENTIAL_IO(LINE); use LINE_IO;  -- 2
  6956.        package SCREEN_IO is new SEQUENTIAL_IO(SCREEN); use SCREEN_IO;  -- 3
  6957.     begin
  6958.        null;
  6959.     end IO;
  6960.  
  6961. No, the instantiation of SEQUENTIAL_IO for the subtype LINE is correct.
  6962. 1HPlease type a space to go on, or B or Q to go back to the question.                                                                1911 521B517Q517$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    with TEXT_IO, SEQUENTIAL_IO; use TEXT_IO, SEQUENTIAL_IO;  -- 1
  6963.     procedure IO is
  6964.        subtype LINE is STRING(1 .. 80);
  6965.        type SCREEN is array(1 .. 24) of LINE;
  6966.        package LINE_IO is new SEQUENTIAL_IO(LINE); use LINE_IO;  -- 2
  6967.        package SCREEN_IO is new SEQUENTIAL_IO(SCREEN); use SCREEN_IO;  -- 3
  6968.     begin
  6969.        null;
  6970.     end IO;
  6971.  
  6972. No, the instantiation of SEQUENTIAL_IO for the type SCREEN is correct.
  6973. 1HPlease type a space to go on, or B or Q to go back to the question.                                                                 2936 522B517$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      SUBPROGRAM PARAMETERS WITH GENERICS
  6974.  
  6975. The generic part of a subprogram or package can specify a dummy subprogram as
  6976. well as a dummy type.  This is similar to using subprograms as arguments
  6977. (parameters) in Algol and Pascal, and to using the little-known keyword
  6978. EXTERNAL in Fortran.  In Ada, we simply precede the dummy subprogram
  6979. specification with the keyword with in the generic part.  This use of the word
  6980. with has nothing to do with context clauses.  For example, here's the
  6981. specification of a generic function that has one dummy function specification
  6982. in the generic part:
  6983.  
  6984.  generic
  6985.     with function DUMMY(X : in FLOAT) return FLOAT;
  6986.  function DEFINITE_INTEGRAL(LOWER_LIMIT, UPPER_LIMIT : in FLOAT) return FLOAT;
  6987.  
  6988. We could then write a function COS, instantiate DEFINITE_INTEGRAL for it, and
  6989. use the instantiation as follows:
  6990.  
  6991.  ANSWER : FLOAT;
  6992.  function COS(X : in FLOAT) return FLOAT:
  6993.  function DEFINITE_INTEGRAL_OF_COS is new DEFINITE_INTEGRAL(COS);
  6994.  ANSWER := DEFINITE_INTEGRAL_OF_COS(LOWER_LIMIT => 0.0, UPPER_LIMIT => 1.5708);
  6995. 1HPlease type a space to go on, or B to go back.                                        2755 523B521$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                       REPRESENTATION CLAUSES AND SYSTEM
  6996.  
  6997. Ada normally represents an enumeration type internally with successive integers
  6998. starting at zero.  For example, if we write
  6999.  
  7000.                  type COMMAND is (LEFT, RIGHT, FORWARD, BACK);
  7001.  
  7002. the compiler will normally represent LEFT with 0, RIGHT with 1, etc.  Usually
  7003. this doesn't concern the programmer.  However, after the above declaration, we
  7004. can specify the internal representation with a representation clause like this:
  7005.  
  7006.        for COMMAND use (LEFT => 1, RIGHT => 2, FORWARD => 4, BACK => 8);
  7007.  
  7008. We might want to do that if, for example, we're sending a value of type COMMAND
  7009. to some hardware which will interpret the bit patterns.  The values must be
  7010. assigned in increasing order with no duplications, but gaps are permitted.  The
  7011. attributes SUCC, PRED, POS, and VAL are not affected.  Thus COMMAND'POS(BACK)
  7012. is still 3.
  7013.  
  7014. We can specify the SIZE, in bits, of the objects of a given type:
  7015. 1HPlease type a space to go on, or B to go back.                     2772 524B522$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                          type NUM is range 0 .. 100;
  7016.                           for NUM'SIZE use 8;
  7017.  
  7018. We can specify the STORAGE_SIZE (in bits!) for a task and for a collection of
  7019. accessed objects like a linked list.  If MONITOR is a task and the
  7020. specification for our linked list says type P is access LINK;, we can write
  7021.  
  7022.                      for MONITOR'STORAGE_SIZE use 16_384*8;
  7023.                      for P'STORAGE_SIZE use 32_768*8;
  7024.  
  7025. The attributes SIZE and STORAGE_SIZE can also be used in the usual way:
  7026.  
  7027.                       I : INTEGER := MONITOR'STORAGE_SIZE;
  7028.  
  7029. We can specify the attribute SMALL for a fixed point type:
  7030.  
  7031.                 type VOLTAGE is delta 0.01 range -20.0 .. 20.0;
  7032.                 for VOLTAGE'SMALL use 1.0/128.0;
  7033.  
  7034. Before discussing the remaining types of representation clauses, we must
  7035. briefly mention the package SYSTEM that comes with Ada.  SYSTEM contains
  7036. implementation dependent specifications.
  7037. 1HPlease type a space to go on, or B to go back.    3161 525B523$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A brief outline of package SYSTEM is in section 13.7 of the LRM.  However, the
  7038. full package specification should appear in the documentation that came with
  7039. your compiler.  For all compilers that meet the Ada Standard, the description
  7040. of implementation dependent features (including the specification of package
  7041. SYSTEM) is always in Appendix F of the documentation.  Of interest here are the
  7042. type ADDRESS and the constant STORAGE_UNIT.  In our examples, we'll assume that
  7043. SYSTEM.ADDRESS is some integer type.
  7044.  
  7045. Representation clauses can use the reserved word at followed by a constant of
  7046. type SYSTEM.ADDRESS to specify the absolute address of a variable, a constant,
  7047. a task entry, a procedure, or a package.  The package SYSTEM must be visible.
  7048. This feature is useful for memory-mapped I/O and interrupt handlers, etc.  For
  7049. example:
  7050.  
  7051.                      MODEM_CONTROL : INTEGER;
  7052.                      for MODEM_CONTROL use at 16#FC00#;
  7053.                      task INTERRUPT_HANDLER is
  7054.                         entry CLOCK_INTERRUPT;
  7055.                         for CLOCK_INTERRUPT use at 16#100#;
  7056.                      end INTERRUPT_HANDLER;
  7057.                      procedure KEYSTROKE;
  7058.                      for KEYSTROKE use at 16#200#;
  7059. 1HPlease type a space to go on, or B to go back.               2860 526B524$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Finally, we can use atmod, and range with constants of type
  7060. SYSTEM.STORAGE_UNIT to specify how records are stored.  For example,
  7061.  
  7062.                    type VERY_SHORT_INTEGER is range 0 .. 15;
  7063.                    type PACKED is
  7064.                       record
  7065.                          A, B, C, D : VERY_SHORT_INTEGER;
  7066.                       end record;
  7067.                    for PACKED use
  7068.                       record at mod 2;
  7069.                          A at 0 range 0 .. 3;
  7070.                          B at 0 range 4 .. 7;
  7071.                          C at 1 range 0 .. 3;
  7072.                          D at 1 range 4 .. 7;
  7073.                       end record;
  7074.  
  7075. This forces A and B to be stored in bits 0 .. 3 and 4 .. 7 of byte 0 of the
  7076. record, and C and D to be packed into byte 1.  The optional clause record at
  7077. mod 2; specifies that all records of type PACKED will begin at even addresses.
  7078.  
  7079. An implementation of Ada need not accept most representation clauses to meet
  7080. the standard.  If any clause is rejected, an error message will be printed.
  7081. 1HPlease type a space to go on, or B to go back.                146625271528B525$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                type ANSWER is (YES, NO, MAYBE);
  7082.                 for ANSWER use (YES => 1, NO => 2, MAYBE => 4);
  7083.  
  7084. What is ANSWER'VAL(2)?
  7085.  
  7086.  
  7087. 1.  ANSWER'VAL(2) is NO.
  7088.  
  7089. 2.  ANSWER'VAL(2) is MAYBE.
  7090. 1HPlease press 1 or 2, or B to go back.          1665 529B526Q526$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                type ANSWER is (YES, NO, MAYBE);
  7091.                 for ANSWER use (YES => 1, NO => 2, MAYBE => 4);
  7092.  
  7093.  
  7094. You're right!  The representation clause doesn't affect the attributes POS and
  7095. VAL, and positions are numbered from zero.  So ANSWER'VAL(2) is MAYBE.
  7096. 1HPlease type a space to go on, or B or Q to go back to the question.           1626 529B526Q526$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                type ANSWER is (YES, NO, MAYBE);
  7097.                 for ANSWER use (YES => 1, NO => 2, MAYBE => 4);
  7098.  
  7099.  
  7100. No, the representation clause doesn't affect the attributes POS and VAL, and
  7101. positions are numbered from zero.  So ANSWER'VAL(2) is MAYBE.
  7102. 1HPlease type a space to go on, or B or Q to go back to the question.                                                  2833 530B526$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                UNCHECKED CONVERSION AND UNCHECKED DEALLOCATION
  7103.  
  7104. Ada comes with a generic function UNCHECKED_CONVERSION and a generic procedure
  7105. UNCHECKED_DEALLOCATION.  They can be instantiated for any type.  Both are
  7106. somewhat dangerous to use, but we'll describe them briefly.  Their
  7107. specifications are:
  7108.  
  7109.             generic
  7110.                type SOURCE is limited private;
  7111.                type TARGET is limited private;
  7112.             function UNCHECKED_CONVERSION(S : SOURCE) return TARGET;
  7113.  
  7114.             generic
  7115.                type OBJECT is limited private;
  7116.                type NAME   is access OBJECT;
  7117.             procedure UNCHECKED_DEALLOCATION(X : in out NAME);
  7118.  
  7119. UNCHECKED_CONVERSION "converts" from one type to another without doing any
  7120. arithmetic or bit manipulation.  In other words, it lets us look at an object
  7121. of one type as if it were of another type.  The effect is similar to the use
  7122. of EQUIVALENCE in Fortran.  The results may be unpredictable unless the two
  7123. types occupy the same amount of storage.
  7124. 1HPlease type a space to go on, or B to go back.                                           3215 531B529$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$One use of UNCHECKED_CONVERSION might be to allow us to and two INTEGERs.  Some
  7125. Ada compilers come with a package that enables us to do that, but many
  7126. compilers have no such package.  Suppose that types INTEGER and BOOLEAN occupy
  7127. the same amount of storage.  If our program says with UNCHECKED_CONVERSION; we
  7128. could write
  7129.  
  7130.       function INT_TO_BOOL is new UNCHECKED_CONVERSION(INTEGER, BOOLEAN);
  7131.       function BOOL_TO_INT is new UNCHECKED_CONVERSION(BOOLEAN, INTEGER);
  7132.       function "and"(LEFT, RIGHT : in INTEGER) return INTEGER is
  7133.       begin
  7134.          return BOOL_TO_INT(INT_TO_BOOL(LEFT) and INT_TO_BOOL(RIGHT));
  7135.       end "and";
  7136.  
  7137. Using UNCHECKED_CONVERSION usually destroys program portability.
  7138.  
  7139. UNCHECKED_DEALLOCATION allows us to free the memory occupied by an object
  7140. associated with a pointer.  Normally, the system reclaims memory when it's
  7141. needed.  However, the execution time for that so-called garbage collection
  7142. tends to be long and unpredictable.  Suppose we have type P is access LINK; and
  7143. HEAD : P;.  Also suppose that we no longer need the object pointed to by HEAD,
  7144. and we're sure that no other pointer points to the same object as HEAD.  If our
  7145. program says with UNCHECKED_DEALLOCATION; we can write
  7146. 1HPlease type a space to go on, or B to go back.                                                             2050 532B530$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$             procedure FREE is new UNCHECKED_DEALLOCATION(LINK, P);
  7147.              ...
  7148.              FREE(HEAD);
  7149.  
  7150. This will release the memory occupied by the object pointed to by HEAD, and
  7151. then set HEAD to null.  But there's a danger.  If there's another pointer that
  7152. pointed to the same object, it now points to released memory.  A reference to
  7153. that pointer will have unpredictable results.  In general, it's best to let the
  7154. system handle the reclaiming of memory.  That way there's no danger of dangling
  7155. references.
  7156. 1HPlease type a space to go on, or B to go back.                          3130 533B531$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                                    PRAGMAS
  7157.  
  7158. pragma is a message to the compiler.  The pragmas that are predefined by Ada
  7159. are all described in Appendix B of the LRM; we'll discuss the most important
  7160. ones here.  A particular version of Ada need not implement all the predefined
  7161. pragmas, and it may add some of its own.  (One version of Ada adds a pragma
  7162. TIME_SLICE, used with tasking.)  Unlike representation clauses, unimplemented
  7163. predefined pragmas do not cause error messages; the compiler simply ignores
  7164. them.  This enhances program portability.  Any additional pragmas added by a
  7165. particular implementation of Ada will be explained in Appendix F of the
  7166. compiler documentation.  The most important predefined pragmas are these:
  7167.  
  7168. The statements pragma LIST(ON); and pragma LIST(OFF); turn on and off the
  7169. compiler listing.  Also, pragma PAGE; will cause the compiler listing to start
  7170. a new page, if the listing is turned on.  These pragmas are allowed almost
  7171. anywhere in the program.
  7172.  
  7173. Within the declarative region we can write pragma OPTIMIZE(TIME); or pragma
  7174. OPTIMIZE(SPACE); to ask the compiler to optimize the program for minimum
  7175. execution time or minimum memory usage.
  7176. 1HPlease type a space to go on, or B to go back.                                              3361 534B532$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$We can write pragma INLINE(...); with the name of a subprogram to ask the
  7177. compiler to write inline code in place of every call to the subprogram.  Even
  7178. versions of Ada that implement this pragma will ignore it if the subprogram is
  7179. recursive.
  7180.  
  7181. We can interface a subprogram written in another language by writing pragma
  7182. INTERFACE(..., ...); after the subprogram specification.  The two arguments are
  7183. the name of the language and the subprogram name.  Consult the compiler
  7184. documentation for information on bringing the object file into the Ada library.
  7185.  
  7186. We can ask the compiler to minimize memory occupied by a record or array by
  7187. writing, after the type declaration, pragma PACK(...); with the name of the
  7188. type.  Note that the specification for package STANDARD (in Appendix C of the
  7189. LRM) contains pragma PACK(STRING); after the definition of type STRING.
  7190.  
  7191. Package SYSTEM defines a subtype of INTEGER called PRIORITY.  We can assign a
  7192. priority to a task by writing, in the specification, pragma PRIORITY(...); with
  7193. an argument of subtype SYSTEM.PRIORITY.  Higher numbers denote greater urgency.
  7194.  
  7195. The pragma SUPPRESS can be used to ask the compiler to turn off certain checks,
  7196. such as CONSTRAINT_ERROR.  It's dangerous and shouldn't be used unless
  7197. absolutely necessary because of time or memory constraints.
  7198. 1HPlease type a space to go on, or B to go back.               1514253515363537B533$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In the author's opinion, which one of these is not dangerous?
  7199.  
  7200.  
  7201.                       1.  UNCHECKED_DEALLOCATION
  7202.  
  7203.                       2.  pragma PACK
  7204.  
  7205.                       3.  pragma SUPPRESS
  7206. 1HPlease press 1, 2, or 3, or B to go back.                                                              1949 538B534Q534$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      1.  UNCHECKED_DEALLOCATION
  7207.  
  7208.                       2.  pragma PACK
  7209.  
  7210.                       3.  pragma SUPPRESS
  7211.  
  7212.  
  7213. You're right!  The worst pragma PACK could do is slow the program down, and
  7214. this pragma is used in package STANDARD.  UNCHECKED_DEALLOCATION could allow a
  7215. pointer to point to memory that has been released, with unpredictable results.
  7216. SUPPRESS could allow a program to use a subscript that's out of range, etc.
  7217. 1HPlease type a space to go on, or B or Q to go back to the question.                           1652 538B534Q534$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      1.  UNCHECKED_DEALLOCATION
  7218.  
  7219.                       2.  pragma PACK
  7220.  
  7221.                       3.  pragma SUPPRESS
  7222.  
  7223.  
  7224. No, UNCHECKED_DEALLOCATION is dangerous because it could allow a pointer to
  7225. point to memory that has been released, with unpredictable results.
  7226. 1HPlease type a space to go on, or B or Q to go back to the question.                        1612 538B534Q534$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                      1.  UNCHECKED_DEALLOCATION
  7227.  
  7228.                       2.  pragma PACK
  7229.  
  7230.                       3.  pragma SUPPRESS
  7231.  
  7232.  
  7233. No, SUPPRESS is dangerous because it could allow a program to use a subscript
  7234. that's out of range, etc.
  7235. 1HPlease type a space to go on, or B or Q to go back to the question.                                                                3328 539B534$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                            LOOSE ENDS AND PITFALLS
  7236.  
  7237. In this final section, we cover some miscellaneous topics that were omitted
  7238. earlier for simplicity.  We also mention some common errors made by Ada
  7239. programmers.  Beginners aren't expected to understand every paragraph until
  7240. they've gained more experience, and we won't ask questions in this section.
  7241.  
  7242. Some terminals and printers don't support the entire ASCII character set.  In
  7243. an Ada program, the vertical bar | may be replaced with the exclamation mark !,
  7244. as in when 3 ! 5 =>.  Also, a pair of sharp signs # may be replaced with a pair
  7245. of colons :, as in 16:FC03:.  The quotation marks around a string constant may
  7246. be replaced with percent signs if the string doesn't contain any quotation
  7247. marks.  In that case, any percent signs within the string must be doubled.
  7248. These character replacements shouldn't be used in programs if the equipment
  7249. will support the standard characters.
  7250.  
  7251. An expression is called static if it can be evaluated at compile time.  In
  7252. almost every case where a constant normally appears, a static expression may
  7253. also be used.  For example, an address representation clause normally takes
  7254. a constant of type SYSTEM.ADDRESS.  A static expression of this type is also
  7255. acceptable, as in for CLOCK_INTERRUPT use at 16*16;.
  7256. 1HPlease type a space to go on, or B to go back.                                                3622 540B538$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$The unary minus is always an operator and never part of a constant.  Thus -5
  7257. is actually a static expression and not a constant.  Normally, this doesn't
  7258. concern the programmer, because, as we just said, static expressions can
  7259. usually appear where a constant appears.  However, in a few special situations
  7260. we can get into trouble.  For example, we can write for I in 10 .. 20 loop and
  7261. A : array(10 .. 20) of FLOAT; but we can't omit the words INTEGER range in
  7262. for I in INTEGER range -10 .. 10 loop and A : array(INTEGER range -10 .. 10) of
  7263. FLOAT;!  Also, if a package P declares type COUNT is new INTEGER; then the
  7264. unary minus operator for that type is part of the package.  If our program
  7265. withs but doesn't use P, we can write A : P.COUNT := 1; but not
  7266. B : P.COUNT := -1;.  We either have to use the package, rename P."-", or write
  7267. B : P.COUNT := P."-"(1);.
  7268.  
  7269. The operators have precedence, so that 1 + 2 * 3 means 1 + (2 * 3).  The
  7270. precedence of all the operators is given in section 4.5 of the LRM.  A
  7271. programmer should never have to look these up, because parentheses should be
  7272. used for any cases that aren't obvious.  Unary minus has a low precedence, so
  7273. -A mod B means -(A mod B).
  7274.  
  7275. If we write A, B : array(1 .. 5) of FLOAT; then A and B have different
  7276. anonymous types, and we can't write A := B;.  To fix this, write
  7277. type VECTOR5 is array(1 .. 5) of FLOAT; and then A, B : VECTOR5;.
  7278. 1HPlease type a space to go on, or B to go back.                                                      2840 541B539$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Ada will automatically convert from a universal type to a named type, but not
  7279. from a named type to a universal.  For example,
  7280.  
  7281.                     C1 : constant INTEGER := 1;  -- legal
  7282.                     C2 : constant INTEGER := 2;  -- legal
  7283.                     C3 : constant := C1 + C2;    -- illegal
  7284.  
  7285. When arrays are assigned, the subscripts don't have to match; only the lengths
  7286. and types of the elements need match.  But if a formal parameter ("dummy
  7287. argument") of a subprogram is a constrained array, the subscripts in the call
  7288. to the subprogram must match.  For example, the last line here will raise
  7289. CONSTRAINT_ERROR:
  7290.  
  7291.                       subtype NAME is STRING(1 .. 30);
  7292.                       JOHN : NAME;
  7293.                       LINE : STRING(1 .. 80);
  7294.                       procedure DISPLAY(PERSON : in NAME);
  7295.                       ...
  7296.                       JOHN := LINE(51 .. 80);   -- legal
  7297.                       DISPLAY(LINE( 1 .. 30));  -- legal
  7298.                       DISPLAY(LINE(51 .. 80));  -- illegal
  7299. 1HPlease type a space to go on, or B to go back.                                    2847 542B540$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$When a subprogram formal parameter is an unconstrained array, beginners often
  7300. wrongly assume that the subscripts will start with one.  For example,
  7301.  
  7302.                       LINE : STRING(1 .. 80);
  7303.                       procedure DISPLAY(S : in STRING) is
  7304.                       begin
  7305.                          for I in 1 .. S'LENGTH loop
  7306.                             ... S(I) ...
  7307.  
  7308. This will raise CONSTRAINT_ERROR if we call DISPLAY(LINE(51 .. 80));.  The for
  7309. statement should be changed to say for I in S'RANGE loop.
  7310.  
  7311. Remember that elaboration occurs at run time.  The following raises
  7312. PROGRAM_ERROR by trying to activate a task before elaborating its body:
  7313.  
  7314.                            task type T is ... end T;
  7315.                            type P is access T;
  7316.                            T1 : P := new T;
  7317.                            task body T is ... end T;
  7318.  
  7319. The third line should be changed to T1 : P; and the statement T1 := new T;
  7320. should be placed in the executable region.
  7321. 1HPlease type a space to go on, or B to go back.                             3134 543B541$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A return statement in a function is used with an object: return ANSWER;.
  7322. However, return may also appear without an object in a procedure; we simply
  7323. write return;.  Normally, a procedure returns after executing its last
  7324. statement, but an early return is possible by this method.  Well structured
  7325. programs don't use this feature of Ada.
  7326.  
  7327. Some implementations of Ada provide a package LOW_LEVEL_IO which includes
  7328. overloaded procedures SEND_CONTROL and RECEIVE_CONTROL to interface various
  7329. hardware devices directly.  This package is completely implementation
  7330. dependent, so you'll have to consult Appendix F of your compiler documentation.
  7331.  
  7332. In the rare case of an aggregate containing just one element, we must use named
  7333. rather than positional notation.  For example, the last line is illegal in
  7334.  
  7335.                 type VECTOR is array(INTEGER range <>) of FLOAT;
  7336.                 A : VECTOR(1 .. 1);
  7337.                 ...
  7338.                 A := (1 => 2.3);  -- legal
  7339.                 A := (2.3);  -- illegal
  7340.  
  7341. because the right hand side is a FLOAT rather than an array of one FLOAT.  It's
  7342. OK to use positional notation in calls to subprograms with only one argument.
  7343. 1HPlease type a space to go on, or B to go back.                                          2739 544B542$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$In the unusual case of a for loop index hiding an explicitly declared object of
  7344. the same name, the explicitly declared object can be accessed inside the loop.
  7345. Simply use dot notation with the name of the compilation unit (procedure,
  7346. function, etc.)  For example, the following is legal:
  7347.  
  7348.                            procedure MAIN is
  7349.                               IX : FLOAT;
  7350.                               J  : INTEGER;
  7351.                            begin
  7352.                               IX := 3.2;
  7353.                               for IX in 1 .. 10 loop
  7354.                                  MAIN.IX := 6.0;
  7355.                                  J := IX;
  7356.                               end loop;
  7357.                            end MAIN;
  7358.  
  7359. Inside the loop, IX refers to the loop index, and the explicitly declared
  7360. object can be accessed by writing MAIN.IX.  Outside the loop, IX refers to the
  7361. explicitly declared object, and the loop index doesn't exist.
  7362. 1HPlease type a space to go on, or B to go back.                                     3028 101B543$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Well, we haven't covered all there is to know about Ada, but this has been a
  7363. very thorough course.  If you've come this far and completed the six Outside
  7364. Assignments, you should be a very good Ada programmer.  To be an excellent Ada
  7365. programmer, start doing all your casual programming in Ada.  If you need a
  7366. simple program to balance your checkbook, write it in Ada!  At this point,
  7367. switching to Ada for all your programming will do you much more good than
  7368. further instruction from a tutor program.
  7369.  
  7370. The best way to answer any remaining questions about Ada is to "ask the
  7371. compiler" by writing a brief test program, especially if your compiler is
  7372. validated.  You can also look in the LRM, which, by definition, does cover all
  7373. of the Ada language.  However, the LRM isn't easy reading!
  7374.  
  7375. The best way to debug a short program is often to execute it by hand, with
  7376. pencil and paper.  You can also add extra statements to the program to display
  7377. intermediate results, and remove them later.
  7378.  
  7379. We wish you success with Ada, and welcome your comments and suggestions!
  7380.  
  7381. Now, you can press B to go back,
  7382.  
  7383.                   or, for one last time ...
  7384. 1H                          ... type a space to go on.